cfad47cfa3/t3compiler/tads3/test/data/mod_bignum.t

4b825dc642cb6eb9a060e54bf8d69288fbee4904cfad47cfa334b206c65f22086bcc5d63e6f70944
1
#include "tads.h"
2
#include "t3.h"
3
#include "bignum.h"
4
5
preinit()
6
{
7
}
8
9
main(args)
10
{
11
    local x;
12
13
    x = 1.00000000000e8 / 3;
14
    tadsSay(x.spellNumber());
15
    "\b";
16
17
    "log2(32) = << (32.0000).log2() >>\n";
18
    "log2(55) = << (55.0000000).log2() >>\n";
19
}
20
21
modify BigNumber
22
    log2()
23
    {
24
        /* 
25
         *   cache ln(2) with slightly greater precision than our value -
26
         *   if we already have a precise enough value cached, there's no
27
         *   need to cache it again 
28
         */
29
        if (BigNumber.cacheLn2_ == nil
30
            || BigNumber.cacheLn2_.getPrecision() < getPrecision() + 3)
31
            BigNumber.cacheLn2_ = new BigNumber(2, getPrecision() + 3).logE();
32
33
        /* 
34
         *   calculate ln(self) to slightly greater than the required
35
         *   precision, to avoid rounding error, then divide by the cached
36
         *   value of ln(2) to yield the log base 2 of self 
37
         */
38
        return (self.setPrecision(getPrecision() + 3).logE()
39
                / BigNumber.cacheLn2_).setPrecision(getPrecision());
40
    }
41
    cacheLn2_ = nil
42
    
43
    spellNumber()
44
    {
45
        local str;
46
        local val = self;
47
        local units = ['one', 'two', 'three', 'four', 'five',
48
                       'six', 'seven', 'eight', 'nine', 'ten'];
49
50
        /* start out with an empty string */
51
        str = '';
52
53
        /* if the value is exactly zero, it's a special case */
54
        if (val == 0.0)
55
            return 'zero';
56
57
        /* 
58
         *   if it's negative, start the string with 'minus' and change
59
         *   the value we're working with to positive 
60
         */
61
        if (val < 0.0)
62
        {
63
            str = 'minus ';
64
            val = -val;
65
        }
66
67
        /* do the billions */
68
        if (val > 1.0e9)
69
        {
70
            /* add the billions */
71
            str += (val / 1.0e9).getWhole().spellNumber() + ' billion ';
72
73
            /* remove the billions portion */
74
            val -= (val / 1.0e9).getWhole() * 1.0e9;
75
        }
76
77
        /* do the millions */
78
        if (val > 1.0e6)
79
        {
80
            /* add the millions */
81
            str += (val / 1.0e6).getWhole().spellNumber() + ' million ';
82
83
            /* remove the millions portion */
84
            val -= (val / 1.0e6).getWhole() * 1.0e6;
85
        }
86
87
        /* do the thousands */
88
        if (val > 1.0e3)
89
        {
90
            /* add the number of thousands */
91
            str += (val / 1.0e3).getWhole().spellNumber() + ' thousand ';
92
93
            /* remove the thousands */
94
            val -= (val / 1.0e3).getWhole() * 1.0e3;
95
        }
96
97
        /* do the hundreds */
98
        if (val > 100.0)
99
        {
100
            /* add the number of hundreds */
101
            str += units[toInteger(val / 100.0)] + ' hundred ';
102
103
            /* remove the hundreds */
104
            val -= (val / 100.0).getWhole() * 100.0;
105
        }
106
107
        /* do the rest */
108
        if (val >= 20.0)
109
        {
110
            /* add the tens name */
111
            str += ['twenty', 'thirty', 'forty', 'fifty', 'sixty',
112
                    'seventy', 'eighty', 'ninety']
113
                   [toInteger(val / 10.0) - 1];
114
115
            /* remove the tens */
116
            val -= (val / 10.0).getWhole() * 10.0;
117
118
            /* if there's anything left, add it */
119
            if (val != 0)
120
                str += '-' + units[toInteger(val)];
121
        }
122
        else if (val >= 10.0)
123
        {
124
            /* add the 'teen' name */
125
            str += ['ten', 'eleven', 'twelve', 'thirteen', 'forteen',
126
                    'fifteen', 'sixteen', 'seventeen', 'eighteen',
127
                    'nineteen'][toInteger(val) - 9];
128
        }
129
        else if (val >= 0.0)
130
        {
131
            /* only the units remain */
132
            str += units[toInteger(val)];
133
        }
134
        else
135
        {
136
            /* 
137
             *   we're not adding anything more - we left a trailing space
138
             *   in case we were going to add something, so remove it 
139
             */
140
            str = str.substr(1, str.length() - 1);
141
        }
142
143
        /* return the result */
144
        return str;
145
    }
146
;
147