| | 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 | |