1096 ! ! |
1099 ! ! |
1097 |
1100 |
1098 !LargeFloat methodsFor:'initialization'! |
1101 !LargeFloat methodsFor:'initialization'! |
1099 |
1102 |
1100 setPrecisionTo: n |
1103 setPrecisionTo: n |
1101 precision _ n. |
1104 precision := n. |
1102 self roundToPrecision |
1105 self roundToPrecision |
1103 |
1106 |
1104 "Modified: / 28-05-2019 / 11:22:21 / Claus Gittinger" |
1107 "Modified: / 28-05-2019 / 11:22:21 / Claus Gittinger" |
|
1108 "Modified (format): / 28-05-2019 / 17:45:16 / Claus Gittinger" |
1105 ! ! |
1109 ! ! |
1106 |
1110 |
1107 !LargeFloat methodsFor:'mathematical functions'! |
1111 !LargeFloat methodsFor:'mathematical functions'! |
1108 |
1112 |
1109 agm: aNumber |
1113 agm: aNumber |
1110 "Answer the arithmetic geometric mean of self and aNumber" |
1114 "Answer the arithmetic geometric mean of self and aNumber" |
1111 |
1115 |
1112 | a b am gm | |
1116 | a b am gm | |
1113 a _ self. |
1117 a := self. |
1114 b _ aNumber. |
1118 b := aNumber. |
1115 |
1119 |
1116 [am _ a + b timesTwoPower: -1. "am is arithmetic mean" |
1120 [am := a + b timesTwoPower: -1. "am is arithmetic mean" |
1117 gm _ (a * b) sqrt. "gm is geometric mean" |
1121 gm := (a * b) sqrt. "gm is geometric mean" |
1118 a = am or: [b = gm]] |
1122 a = am or: [b = gm]] |
1119 whileFalse: |
1123 whileFalse: |
1120 [a _ am. |
1124 [a := am. |
1121 b _ gm]. |
1125 b := gm]. |
1122 ^am |
1126 ^am |
|
1127 |
|
1128 "Modified (format): / 28-05-2019 / 17:42:34 / Claus Gittinger" |
1123 ! |
1129 ! |
1124 |
1130 |
1125 arCosh |
1131 arCosh |
1126 "Evaluate the area hyperbolic cosine of the receiver." |
1132 "Evaluate the area hyperbolic cosine of the receiver." |
1127 |
1133 |
1128 | arCosh x one y two | |
1134 | arCosh x one y two | |
1129 x _ self asLargeFloatPrecision: 16 + precision. |
1135 x := self asLargeFloatPrecision: 16 + precision. |
1130 one _ x one. |
1136 one := x one. |
1131 x < one ifTrue: [DomainError signal: 'cannot compute arCosh of a number less than 1']. |
1137 x < one ifTrue: [DomainError signal: 'cannot compute arCosh of a number less than 1']. |
1132 x = one ifTrue: [^self zero]. |
1138 x = one ifTrue: [^self zero]. |
1133 y _ x - one. |
1139 y := x - one. |
1134 y < one |
1140 y < one |
1135 ifTrue: |
1141 ifTrue: |
1136 [y exponent * -4 >= precision |
1142 [y exponent * -4 >= precision |
1137 ifTrue: [arCosh _ (y powerExpansionArCoshp1Precision: y precision) * (y timesTwoPower: 1) sqrt] |
1143 ifTrue: [arCosh := (y powerExpansionArCoshp1Precision: y precision) * (y timesTwoPower: 1) sqrt] |
1138 ifFalse: |
1144 ifFalse: |
1139 [two _ one timesTwoPower: 1. |
1145 [two := one timesTwoPower: 1. |
1140 arCosh _ ((y * (y + two)) sqrt + y + one) ln]] |
1146 arCosh := ((y * (y + two)) sqrt + y + one) ln]] |
1141 ifFalse: [arCosh _ ((x squared - one) sqrt + x) ln]. |
1147 ifFalse: [arCosh := ((x squared - one) sqrt + x) ln]. |
1142 ^arCosh asLargeFloatPrecision: precision |
1148 ^arCosh asLargeFloatPrecision: precision |
|
1149 |
|
1150 "Modified (format): / 28-05-2019 / 17:42:40 / Claus Gittinger" |
1143 ! |
1151 ! |
1144 |
1152 |
1145 arSinh |
1153 arSinh |
1146 "Evaluate the area hyperbolic sine of the receiver." |
1154 "Evaluate the area hyperbolic sine of the receiver." |
1147 |
1155 |
1148 | arSinh x one | |
1156 | arSinh x one | |
1149 self isZero ifTrue: [^self]. |
1157 self isZero ifTrue: [^self]. |
1150 self exponent negated > precision ifTrue: [^self]. |
1158 self exponent negated > precision ifTrue: [^self]. |
1151 x _ self asLargeFloatPrecision: 16 + precision. |
1159 x := self asLargeFloatPrecision: 16 + precision. |
1152 x inPlaceAbs. |
1160 x inPlaceAbs. |
1153 self exponent * -4 >= precision |
1161 self exponent * -4 >= precision |
1154 ifTrue: [arSinh _ x powerExpansionArSinhPrecision: x precision] |
1162 ifTrue: [arSinh := x powerExpansionArSinhPrecision: x precision] |
1155 ifFalse: |
1163 ifFalse: |
1156 [one _ x one. |
1164 [one := x one. |
1157 arSinh _ ((x squared + one) sqrt + x) ln]. |
1165 arSinh := ((x squared + one) sqrt + x) ln]. |
1158 self negative ifTrue: [arSinh inPlaceNegated]. |
1166 self negative ifTrue: [arSinh inPlaceNegated]. |
1159 ^arSinh asLargeFloatPrecision: precision |
1167 ^arSinh asLargeFloatPrecision: precision |
|
1168 |
|
1169 "Modified (format): / 28-05-2019 / 17:42:45 / Claus Gittinger" |
1160 ! |
1170 ! |
1161 |
1171 |
1162 arTanh |
1172 arTanh |
1163 "Evaluate the area hyperbolic tangent of the receiver." |
1173 "Evaluate the area hyperbolic tangent of the receiver." |
1164 |
1174 |
1165 | arTanh x one | |
1175 | arTanh x one | |
1166 self isZero ifTrue: [^self]. |
1176 self isZero ifTrue: [^self]. |
1167 x _ self asLargeFloatPrecision: 16 + precision. |
1177 x := self asLargeFloatPrecision: 16 + precision. |
1168 x inPlaceAbs. |
1178 x inPlaceAbs. |
1169 one _ x one. |
1179 one := x one. |
1170 x >= one ifTrue: [DomainError signal: 'cannot evaluate arTanh of number of magnitude >= 1']. |
1180 x >= one ifTrue: [DomainError signal: 'cannot evaluate arTanh of number of magnitude >= 1']. |
1171 self exponent * -4 >= precision |
1181 self exponent * -4 >= precision |
1172 ifTrue: [arTanh _ x powerExpansionArTanhPrecision: x precision] |
1182 ifTrue: [arTanh := x powerExpansionArTanhPrecision: x precision] |
1173 ifFalse: |
1183 ifFalse: |
1174 [arTanh _ ((one + x) / (one - x)) ln. |
1184 [arTanh := ((one + x) / (one - x)) ln. |
1175 arTanh inPlaceTimesTwoPower: -1]. |
1185 arTanh inPlaceTimesTwoPower: -1]. |
1176 self negative ifTrue: [arTanh inPlaceNegated]. |
1186 self negative ifTrue: [arTanh inPlaceNegated]. |
1177 ^arTanh asLargeFloatPrecision: precision |
1187 ^arTanh asLargeFloatPrecision: precision |
|
1188 |
|
1189 "Modified (format): / 28-05-2019 / 17:42:49 / Claus Gittinger" |
1178 ! |
1190 ! |
1179 |
1191 |
1180 arcCos |
1192 arcCos |
1181 "Evaluate the arc cosine of the receiver." |
1193 "Evaluate the arc cosine of the receiver." |
1182 |
1194 |
1301 |
1313 |
1302 "Modified (format): / 28-05-2019 / 16:17:10 / Claus Gittinger" |
1314 "Modified (format): / 28-05-2019 / 16:17:10 / Claus Gittinger" |
1303 ! |
1315 ! |
1304 |
1316 |
1305 exp |
1317 exp |
1306 "Answer the exponential of the receiver." |
1318 "Answer the exponential of the receiver." |
1307 |
1319 |
1308 | ln2 x q r ri res n maxIter p one two | |
1320 | ln2 x q r ri res n maxIter p one two | |
1309 one _ self one. |
1321 one := self one. |
1310 two _ one timesTwoPower: 1. |
1322 two := one timesTwoPower: 1. |
1311 "Use following decomposition: |
1323 "Use following decomposition: |
1312 x exp = (2 ln * q + r) exp. |
1324 x exp = (2 ln * q + r) exp. |
1313 x exp = (2**q * r exp)" |
1325 x exp = (2**q * r exp)" |
1314 ln2 _ two ln. |
1326 ln2 := two ln. |
1315 x _ self / ln2. |
1327 x := self / ln2. |
1316 q _ x truncated. |
1328 q := x truncated. |
1317 r _ (x - q) * ln2. |
1329 r := (x - q) * ln2. |
1318 |
1330 |
1319 "now compute r exp by power series expansion |
1331 "now compute r exp by power series expansion |
1320 we compute (r/(2**p)) exp ** (2**p) in order to have faster convergence" |
1332 we compute (r/(2**p)) exp ** (2**p) in order to have faster convergence" |
1321 p _ 10 min: precision // 2. |
1333 p := 10 min: precision // 2. |
1322 r _ r timesTwoPower: p negated. |
1334 r := r timesTwoPower: p negated. |
1323 ri _ one asLargeFloatPrecision: precision + 16. |
1335 ri := one asLargeFloatPrecision: precision + 16. |
1324 res _ ri copy. |
1336 res := ri copy. |
1325 n _ 0. |
1337 n := 0. |
1326 maxIter _ 1 + ((precision + 16) / p) ceiling. |
1338 maxIter := 1 + ((precision + 16) / p) ceiling. |
1327 [n <= maxIter] whileTrue: |
1339 [n <= maxIter] whileTrue: |
1328 [n _ n + 1. |
1340 [n := n + 1. |
1329 ri inPlaceMultiplyBy: r / n. |
1341 ri inPlaceMultiplyBy: r / n. |
1330 res inPlaceAdd: ri]. |
1342 res inPlaceAdd: ri]. |
1331 p timesRepeat: [res inPlaceMultiplyBy: res]. |
1343 p timesRepeat: [res inPlaceMultiplyBy: res]. |
1332 res inPlaceTimesTwoPower: q. |
1344 res inPlaceTimesTwoPower: q. |
1333 |
1345 |
1334 "now use a Newton iteration to refine the result |
1346 "now use a Newton iteration to refine the result |
1335 res = res * (self - res ln + 1)" |
1347 res = res * (self - res ln + 1)" |
1336 [| oldres delta | |
1348 [| oldres delta | |
1337 oldres _ res. |
1349 oldres := res. |
1338 res _ res asLargeFloatPrecision: res precision + 32. |
1350 res := res asLargeFloatPrecision: res precision + 32. |
1339 res inPlaceMultiplyBy: self - res ln + 1. |
1351 res inPlaceMultiplyBy: self - res ln + 1. |
1340 delta _ (res - oldres) exponent. |
1352 delta := (res - oldres) exponent. |
1341 delta = 0 or: [delta <= (res exponent - precision - 8)]] |
1353 delta = 0 or: [delta <= (res exponent - precision - 8)]] |
1342 whileFalse. |
1354 whileFalse. |
1343 |
1355 |
1344 ^res asLargeFloatPrecision: precision |
1356 ^res asLargeFloatPrecision: precision |
|
1357 |
|
1358 "Modified (comment): / 28-05-2019 / 17:43:06 / Claus Gittinger" |
1345 ! |
1359 ! |
1346 |
1360 |
1347 ln |
1361 ln |
1348 "Answer the neperian logarithm of the receiver." |
1362 "Answer the neperian logarithm of the receiver." |
1349 |
1363 |
1350 | x4 one two p res selfHighRes prec e | |
1364 | x4 one two p res selfHighRes prec e | |
1351 self <= self zero ifTrue: [DomainError signal: 'ln is only defined for x > 0.0']. |
1365 self <= self zero ifTrue: [DomainError signal: 'ln is only defined for x > 0.0']. |
1352 |
1366 |
1353 one _ self one. |
1367 one := self one. |
1354 self = one ifTrue: [^self zero]. |
1368 self = one ifTrue: [^self zero]. |
1355 two _ one timesTwoPower: 1. |
1369 two := one timesTwoPower: 1. |
1356 |
1370 |
1357 "Use Salamin algorithm (approximation is good if x is big enough) |
1371 "Use Salamin algorithm (approximation is good if x is big enough) |
1358 x ln = Pi / (2 * (1 agm: 4/x) ). |
1372 x ln = Pi / (2 * (1 agm: 4/x) ). |
1359 If x not big enough, compute (x timesTwoPower: p) ln - (2 ln * p) |
1373 If x not big enough, compute (x timesTwoPower: p) ln - (2 ln * p) |
1360 if x is close to 1, better use a power expansion" |
1374 if x is close to 1, better use a power expansion" |
1361 prec _ precision + 16. |
1375 prec := precision + 16. |
1362 e _ self exponent. |
1376 e := self exponent. |
1363 e < 0 ifTrue: [e _ -1 - e]. |
1377 e < 0 ifTrue: [e := -1 - e]. |
1364 e > prec |
1378 e > prec |
1365 ifTrue: [p _ 0] |
1379 ifTrue: [p := 0] |
1366 ifFalse: |
1380 ifFalse: |
1367 [p _ prec - e. |
1381 [p := prec - e. |
1368 prec _ prec + p highBit]. |
1382 prec := prec + p highBit]. |
1369 selfHighRes _ self asLargeFloatPrecision: prec. |
1383 selfHighRes := self asLargeFloatPrecision: prec. |
1370 (selfHighRes - one) exponent * -4 >= precision ifTrue: [^(selfHighRes powerExpansionLnPrecision: prec) asLargeFloatPrecision: precision]. |
1384 (selfHighRes - one) exponent * -4 >= precision ifTrue: [^(selfHighRes powerExpansionLnPrecision: prec) asLargeFloatPrecision: precision]. |
1371 self < one ifTrue: [selfHighRes inPlaceReciprocal]. "Use ln(1/x) => - ln(x)" |
1385 self < one ifTrue: [selfHighRes inPlaceReciprocal]. "Use ln(1/x) => - ln(x)" |
1372 x4 _ (4 asLargeFloatPrecision: prec) |
1386 x4 := (4 asLargeFloatPrecision: prec) |
1373 inPlaceDivideBy: selfHighRes; |
1387 inPlaceDivideBy: selfHighRes; |
1374 inPlaceTimesTwoPower: p negated. |
1388 inPlaceTimesTwoPower: p negated. |
1375 res _ selfHighRes pi / (one agm: x4) timesTwoPower: -1. |
1389 res := selfHighRes pi / (one agm: x4) timesTwoPower: -1. |
1376 res _ selfHighRes = two |
1390 res := selfHighRes = two |
1377 ifTrue: [res / (p + 1)] |
1391 ifTrue: [res / (p + 1)] |
1378 ifFalse: [p = 0 ifTrue: [res] ifFalse: [res - ((two asLargeFloatPrecision: prec) ln * p)]]. |
1392 ifFalse: [p = 0 ifTrue: [res] ifFalse: [res - ((two asLargeFloatPrecision: prec) ln * p)]]. |
1379 self < one ifTrue: [res inPlaceNegated]. |
1393 self < one ifTrue: [res inPlaceNegated]. |
1380 ^res asLargeFloatPrecision: precision |
1394 ^res asLargeFloatPrecision: precision |
|
1395 |
|
1396 "Modified (comment): / 28-05-2019 / 17:43:30 / Claus Gittinger" |
1381 ! |
1397 ! |
1382 |
1398 |
1383 sin |
1399 sin |
1384 "Evaluate the sine of the receiver" |
1400 "Evaluate the sine of the receiver" |
1385 |
1401 |
1765 ! ! |
1784 ! ! |
1766 |
1785 |
1767 !LargeFloat methodsFor:'private'! |
1786 !LargeFloat methodsFor:'private'! |
1768 |
1787 |
1769 cos: x |
1788 cos: x |
1770 "Evaluate the cosine of x by recursive cos(2x) formula and power series expansion. |
1789 "Evaluate the cosine of x by recursive cos(2x) formula and power series expansion. |
1771 Note that it is better to use this method with x <= pi/4." |
1790 Note that it is better to use this method with x <= pi/4." |
1772 |
1791 |
1773 | one cos fraction power | |
1792 | one cos fraction power | |
1774 x isZero ifTrue: [^x one]. |
1793 x isZero ifTrue: [^x one]. |
1775 power _ ((precision bitShift: -1) + x exponent max: 0) highBit. |
1794 power := ((precision bitShift: -1) + x exponent max: 0) highBit. |
1776 fraction _ x timesTwoPower: power negated. |
1795 fraction := x timesTwoPower: power negated. |
1777 cos _ fraction powerExpansionCosPrecision: precision + (1 bitShift: 1 + power). |
1796 cos := fraction powerExpansionCosPrecision: precision + (1 bitShift: 1 + power). |
1778 one _ x one. |
1797 one := x one. |
1779 power timesRepeat: |
1798 power timesRepeat: |
1780 ["Evaluate cos(2x)=2 cos(x)^2-1" |
1799 ["Evaluate cos(2x)=2 cos(x)^2-1" |
1781 cos inPlaceMultiplyBy: cos; inPlaceTimesTwoPower: 1; inPlaceSubtract: one]. |
1800 cos inPlaceMultiplyBy: cos; inPlaceTimesTwoPower: 1; inPlaceSubtract: one]. |
1782 ^cos |
1801 ^cos |
|
1802 |
|
1803 "Modified (comment): / 28-05-2019 / 17:42:54 / Claus Gittinger" |
1783 ! |
1804 ! |
1784 |
1805 |
1785 digitCompare: b |
1806 digitCompare: b |
1786 "both are positive or negative. |
1807 "both are positive or negative. |
1787 answer +1 if i am of greater magnitude, -1 if i am of smaller magnitude, 0 if equal magnitude" |
1808 answer +1 if i am of greater magnitude, -1 if i am of smaller magnitude, 0 if equal magnitude" |
1788 |
1809 |
1789 | compare | |
1810 | compare | |
1790 self isZero |
1811 self isZero |
1791 ifTrue: [b isZero |
1812 ifTrue: [b isZero |
1792 ifTrue: [^ 0] |
1813 ifTrue: [^ 0] |
1793 ifFalse: [^ -1]]. |
1814 ifFalse: [^ -1]]. |
1794 b isZero |
1815 b isZero |
1795 ifTrue: [^ 1]. |
1816 ifTrue: [^ 1]. |
1796 compare _ (self exponent - b exponent) sign. |
1817 compare := (self exponent - b exponent) sign. |
1797 ^ compare = 0 |
1818 ^ compare = 0 |
1798 ifTrue: [(self abs - b abs) sign] |
1819 ifTrue: [(self abs - b abs) sign] |
1799 ifFalse: [compare] |
1820 ifFalse: [compare] |
|
1821 |
|
1822 "Modified (comment): / 28-05-2019 / 17:42:59 / Claus Gittinger" |
1800 ! |
1823 ! |
1801 |
1824 |
1802 inPlaceAbs |
1825 inPlaceAbs |
1803 mantissa _ mantissa abs |
1826 mantissa := mantissa abs |
|
1827 |
|
1828 "Modified (format): / 28-05-2019 / 17:43:09 / Claus Gittinger" |
1804 ! |
1829 ! |
1805 |
1830 |
1806 inPlaceAdd: b |
1831 inPlaceAdd: b |
1807 | delta | |
1832 | delta | |
1808 |
1833 |
1809 b isZero ifTrue: [^self roundToPrecision]. |
1834 b isZero ifTrue: [^self roundToPrecision]. |
1810 self isZero ifTrue:[ |
1835 self isZero ifTrue:[ |
1811 mantissa _ b mantissa. |
1836 mantissa := b mantissa. |
1812 biasedExponent _ b biasedExponent |
1837 biasedExponent := b biasedExponent |
1813 ] ifFalse:[ |
1838 ] ifFalse:[ |
1814 biasedExponent = b biasedExponent ifTrue: [ |
1839 biasedExponent = b biasedExponent ifTrue: [ |
1815 mantissa _ mantissa + b mantissa |
1840 mantissa := mantissa + b mantissa |
1816 ] ifFalse:[ |
1841 ] ifFalse:[ |
1817 "check for early truncation. beware, keep 2 bits for rounding" |
1842 "check for early truncation. beware, keep 2 bits for rounding" |
1818 |
1843 |
1819 delta _ biasedExponent - b biasedExponent. |
1844 delta := biasedExponent - b biasedExponent. |
1820 delta - 2 > (precision max: self precisionInMantissa) ifFalse:[ |
1845 delta - 2 > (precision max: self precisionInMantissa) ifFalse:[ |
1821 delta negated - 2 > (precision max: b precisionInMantissa) ifTrue:[ |
1846 delta negated - 2 > (precision max: b precisionInMantissa) ifTrue:[ |
1822 mantissa _ b mantissa. |
1847 mantissa := b mantissa. |
1823 biasedExponent _ b exponent |
1848 biasedExponent := b exponent |
1824 ] ifFalse:[ |
1849 ] ifFalse:[ |
1825 delta _ biasedExponent - b exponent. |
1850 delta := biasedExponent - b exponent. |
1826 delta > 0 ifTrue:[ |
1851 delta > 0 ifTrue:[ |
1827 mantissa _ (self shift: mantissa by: delta) + b mantissa. |
1852 mantissa := (self shift: mantissa by: delta) + b mantissa. |
1828 biasedExponent _ biasedExponent - delta |
1853 biasedExponent := biasedExponent - delta |
1829 ] ifFalse: [ |
1854 ] ifFalse: [ |
1830 mantissa _ mantissa + (self shift: b mantissa by: delta negated) |
1855 mantissa := mantissa + (self shift: b mantissa by: delta negated) |
1831 ] |
1856 ] |
1832 ] |
1857 ] |
1833 ] |
1858 ] |
1834 ] |
1859 ] |
1835 ]. |
1860 ]. |
1836 self roundToPrecision |
1861 self roundToPrecision |
1837 |
1862 |
1838 "Created: / 26-05-2019 / 03:44:50 / Claus Gittinger" |
1863 "Created: / 26-05-2019 / 03:44:50 / Claus Gittinger" |
1839 "Modified: / 28-05-2019 / 08:49:15 / Claus Gittinger" |
1864 "Modified: / 28-05-2019 / 08:49:15 / Claus Gittinger" |
|
1865 "Modified (format): / 28-05-2019 / 17:43:15 / Claus Gittinger" |
1840 ! |
1866 ! |
1841 |
1867 |
1842 inPlaceAddNoRound: b |
1868 inPlaceAddNoRound: b |
1843 | delta | |
1869 | delta | |
1844 |
1870 |
2134 |
2165 |
2135 "Modified (comment): / 26-05-2019 / 03:34:00 / Claus Gittinger" |
2166 "Modified (comment): / 26-05-2019 / 03:34:00 / Claus Gittinger" |
2136 ! |
2167 ! |
2137 |
2168 |
2138 powerExpansionArCoshp1Precision: precBits |
2169 powerExpansionArCoshp1Precision: precBits |
2139 "Evaluate arcosh(x+1)/sqrt(2*x) for the receiver x by power series expansion. |
2170 "Evaluate arcosh(x+1)/sqrt(2*x) for the receiver x by power series expansion. |
2140 The algorithm is interesting when the receiver is close to zero" |
2171 The algorithm is interesting when the receiver is close to zero" |
2141 |
2172 |
2142 | one two count count2 sum term term1 term2 | |
2173 | one two count count2 sum term term1 term2 | |
2143 one _ self one. |
2174 one := self one. |
2144 two _ one timesTwoPower: 1. |
2175 two := one timesTwoPower: 1. |
2145 count _ one copy. |
2176 count := one copy. |
2146 count2 _ one copy. |
2177 count2 := one copy. |
2147 sum _ one copy. |
2178 sum := one copy. |
2148 term1 _ one copy. |
2179 term1 := one copy. |
2149 term2 _ one copy. |
2180 term2 := one copy. |
2150 |
2181 |
2151 [term1 inPlaceMultiplyBy: self. |
2182 [term1 inPlaceMultiplyBy: self. |
2152 term1 inPlaceNegated. |
2183 term1 inPlaceNegated. |
2153 term2 inPlaceMultiplyBy: count2. |
2184 term2 inPlaceMultiplyBy: count2. |
2154 term2 inPlaceMultiplyBy: count2. |
2185 term2 inPlaceMultiplyBy: count2. |
2155 term2 inPlaceDivideBy: count. |
2186 term2 inPlaceDivideBy: count. |
2156 count inPlaceAdd: one. |
2187 count inPlaceAdd: one. |
2157 count2 inPlaceAdd: two. |
2188 count2 inPlaceAdd: two. |
2158 term2 inPlaceDivideBy: count2. |
2189 term2 inPlaceDivideBy: count2. |
2159 term2 inPlaceTimesTwoPower: -2. |
2190 term2 inPlaceTimesTwoPower: -2. |
2160 term _ term1 * term2. |
2191 term := term1 * term2. |
2161 sum inPlaceAdd: term. |
2192 sum inPlaceAdd: term. |
2162 term exponent + precBits < sum exponent] whileFalse. |
2193 term exponent + precBits < sum exponent] whileFalse. |
2163 ^sum |
2194 ^sum |
|
2195 |
|
2196 "Modified (comment): / 28-05-2019 / 17:43:51 / Claus Gittinger" |
2164 ! |
2197 ! |
2165 |
2198 |
2166 powerExpansionArSinhPrecision: precBits |
2199 powerExpansionArSinhPrecision: precBits |
2167 "Evaluate the area hypebolic sine of the receiver by power series expansion. |
2200 "Evaluate the area hypebolic sine of the receiver by power series expansion. |
2168 The algorithm is interesting when the receiver is close to zero" |
2201 The algorithm is interesting when the receiver is close to zero" |
2169 |
2202 |
2170 | one x2 two count sum term | |
2203 | one x2 two count sum term | |
2171 one _ self one. |
2204 one := self one. |
2172 two _ one timesTwoPower: 1. |
2205 two := one timesTwoPower: 1. |
2173 count _ one copy. |
2206 count := one copy. |
2174 sum _ one copy. |
2207 sum := one copy. |
2175 term _ one copy. |
2208 term := one copy. |
2176 x2 _ self squared. |
2209 x2 := self squared. |
2177 |
2210 |
2178 [term inPlaceMultiplyBy: x2. |
2211 [term inPlaceMultiplyBy: x2. |
2179 term inPlaceMultiplyBy: count. |
2212 term inPlaceMultiplyBy: count. |
2180 term inPlaceDivideBy: count + one. |
2213 term inPlaceDivideBy: count + one. |
2181 term inPlaceNegated. |
2214 term inPlaceNegated. |
2182 count inPlaceAdd: two. |
2215 count inPlaceAdd: two. |
2183 sum inPlaceAdd: term / count. |
2216 sum inPlaceAdd: term / count. |
2184 term exponent + precBits < sum exponent] whileFalse. |
2217 term exponent + precBits < sum exponent] whileFalse. |
2185 sum inPlaceMultiplyBy: self. |
2218 sum inPlaceMultiplyBy: self. |
2186 ^sum |
2219 ^sum |
|
2220 |
|
2221 "Modified (comment): / 28-05-2019 / 17:43:57 / Claus Gittinger" |
2187 ! |
2222 ! |
2188 |
2223 |
2189 powerExpansionArTanhPrecision: precBits |
2224 powerExpansionArTanhPrecision: precBits |
2190 "Evaluate the area hyperbolic tangent of the receiver by power series expansion. |
2225 "Evaluate the area hyperbolic tangent of the receiver by power series expansion. |
2191 arTanh (x) = x (1 + x^2/3 + x^4/5 + ... ) for -1 < x < 1 |
2226 arTanh (x) = x (1 + x^2/3 + x^4/5 + ... ) for -1 < x < 1 |
2192 The algorithm is interesting when the receiver is close to zero" |
2227 The algorithm is interesting when the receiver is close to zero" |
2193 |
2228 |
2194 | one x2 two count sum term | |
2229 | one x2 two count sum term | |
2195 one _ self one. |
2230 one := self one. |
2196 two _ one timesTwoPower: 1. |
2231 two := one timesTwoPower: 1. |
2197 count _ one copy. |
2232 count := one copy. |
2198 sum _ one copy. |
2233 sum := one copy. |
2199 term _ one copy. |
2234 term := one copy. |
2200 x2 _ self squared. |
2235 x2 := self squared. |
2201 |
2236 |
2202 [term inPlaceMultiplyBy: x2. |
2237 [term inPlaceMultiplyBy: x2. |
2203 count inPlaceAdd: two. |
2238 count inPlaceAdd: two. |
2204 sum inPlaceAdd: term / count. |
2239 sum inPlaceAdd: term / count. |
2205 term exponent + precBits < sum exponent] whileFalse. |
2240 term exponent + precBits < sum exponent] whileFalse. |
2206 sum inPlaceMultiplyBy: self. |
2241 sum inPlaceMultiplyBy: self. |
2207 ^sum |
2242 ^sum |
|
2243 |
|
2244 "Modified (comment): / 28-05-2019 / 17:44:04 / Claus Gittinger" |
2208 ! |
2245 ! |
2209 |
2246 |
2210 powerExpansionArcSinPrecision: precBits |
2247 powerExpansionArcSinPrecision: precBits |
2211 "Evaluate the arc sine of the receiver by power series expansion. |
2248 "Evaluate the arc sine of the receiver by power series expansion. |
2212 The algorithm is interesting when the receiver is close to zero" |
2249 The algorithm is interesting when the receiver is close to zero" |
2213 |
2250 |
2214 | one x2 two count sum term | |
2251 | one x2 two count sum term | |
2215 one _ self one. |
2252 one := self one. |
2216 two _ one timesTwoPower: 1. |
2253 two := one timesTwoPower: 1. |
2217 count _ one copy. |
2254 count := one copy. |
2218 sum _ one copy. |
2255 sum := one copy. |
2219 term _ one copy. |
2256 term := one copy. |
2220 x2 _ self squared. |
2257 x2 := self squared. |
2221 |
2258 |
2222 [term inPlaceMultiplyBy: x2. |
2259 [term inPlaceMultiplyBy: x2. |
2223 term inPlaceMultiplyBy: count. |
2260 term inPlaceMultiplyBy: count. |
2224 term inPlaceDivideBy: count + one. |
2261 term inPlaceDivideBy: count + one. |
2225 count inPlaceAdd: two. |
2262 count inPlaceAdd: two. |
2226 sum inPlaceAdd: term / count. |
2263 sum inPlaceAdd: term / count. |
2227 term exponent + precBits < sum exponent] whileFalse. |
2264 term exponent + precBits < sum exponent] whileFalse. |
2228 sum inPlaceMultiplyBy: self. |
2265 sum inPlaceMultiplyBy: self. |
2229 ^sum |
2266 ^sum |
|
2267 |
|
2268 "Modified (comment): / 28-05-2019 / 17:44:09 / Claus Gittinger" |
2230 ! |
2269 ! |
2231 |
2270 |
2232 powerExpansionArcTanPrecision: precBits |
2271 powerExpansionArcTanPrecision: precBits |
2233 "Evaluate the arc tangent of the receiver by power series expansion. |
2272 "Evaluate the arc tangent of the receiver by power series expansion. |
2234 arcTan (x) = x (1 - x^2/3 + x^4/5 - ... ) for -1 < x < 1 |
2273 arcTan (x) = x (1 - x^2/3 + x^4/5 - ... ) for -1 < x < 1 |
2235 The algorithm is interesting when the receiver is close to zero" |
2274 The algorithm is interesting when the receiver is close to zero" |
2236 |
2275 |
2237 | count one sum term two x2 | |
2276 | count one sum term two x2 | |
2238 one _ self one. |
2277 one := self one. |
2239 two _ one timesTwoPower: 1. |
2278 two := one timesTwoPower: 1. |
2240 count _ one copy. |
2279 count := one copy. |
2241 sum _ one copy. |
2280 sum := one copy. |
2242 term _ one copy. |
2281 term := one copy. |
2243 x2 _ self squared. |
2282 x2 := self squared. |
2244 |
2283 |
2245 [term inPlaceMultiplyBy: x2. |
2284 [term inPlaceMultiplyBy: x2. |
2246 term inPlaceNegated. |
2285 term inPlaceNegated. |
2247 count inPlaceAdd: two. |
2286 count inPlaceAdd: two. |
2248 sum inPlaceAdd: term / count. |
2287 sum inPlaceAdd: term / count. |
2249 term exponent + precBits < sum exponent] whileFalse. |
2288 term exponent + precBits < sum exponent] whileFalse. |
2250 sum inPlaceMultiplyBy: self. |
2289 sum inPlaceMultiplyBy: self. |
2251 ^sum |
2290 ^sum |
|
2291 |
|
2292 "Modified (comment): / 28-05-2019 / 17:44:15 / Claus Gittinger" |
2252 ! |
2293 ! |
2253 |
2294 |
2254 powerExpansionCosPrecision: precBits |
2295 powerExpansionCosPrecision: precBits |
2255 "Evaluate the cosine of the receiver by power series expansion. |
2296 "Evaluate the cosine of the receiver by power series expansion. |
2256 The algorithm is interesting when the receiver is close to zero" |
2297 The algorithm is interesting when the receiver is close to zero" |
2257 |
2298 |
2258 | count one sum term two x2 | |
2299 | count one sum term two x2 | |
2259 one _ self one. |
2300 one := self one. |
2260 two _ one timesTwoPower: 1. |
2301 two := one timesTwoPower: 1. |
2261 count _ one copy. |
2302 count := one copy. |
2262 sum _ one copy. |
2303 sum := one copy. |
2263 term _ one copy. |
2304 term := one copy. |
2264 x2 _ self squared. |
2305 x2 := self squared. |
2265 |
2306 |
2266 [term inPlaceMultiplyBy: x2. |
2307 [term inPlaceMultiplyBy: x2. |
2267 term inPlaceDivideBy: count * (count + one). |
2308 term inPlaceDivideBy: count * (count + one). |
2268 term inPlaceNegated. |
2309 term inPlaceNegated. |
2269 count inPlaceAdd: two. |
2310 count inPlaceAdd: two. |
2270 sum inPlaceAdd: term. |
2311 sum inPlaceAdd: term. |
2271 term exponent + precBits < sum exponent] whileFalse. |
2312 term exponent + precBits < sum exponent] whileFalse. |
2272 ^sum |
2313 ^sum |
|
2314 |
|
2315 "Modified (comment): / 28-05-2019 / 17:44:25 / Claus Gittinger" |
2273 ! |
2316 ! |
2274 |
2317 |
2275 powerExpansionCoshPrecision: precBits |
2318 powerExpansionCoshPrecision: precBits |
2276 "Evaluate the hyperbolic cosine of the receiver by power series expansion. |
2319 "Evaluate the hyperbolic cosine of the receiver by power series expansion. |
2277 The algorithm is interesting when the receiver is close to zero" |
2320 The algorithm is interesting when the receiver is close to zero" |
2278 |
2321 |
2279 | count one sum term two x2 | |
2322 | count one sum term two x2 | |
2280 one _ self one. |
2323 one := self one. |
2281 two _ one timesTwoPower: 1. |
2324 two := one timesTwoPower: 1. |
2282 count _ one copy. |
2325 count := one copy. |
2283 sum _ one copy. |
2326 sum := one copy. |
2284 term _ one copy. |
2327 term := one copy. |
2285 x2 _ self squared. |
2328 x2 := self squared. |
2286 |
2329 |
2287 [term inPlaceMultiplyBy: x2. |
2330 [term inPlaceMultiplyBy: x2. |
2288 term inPlaceDivideBy: count * (count + one). |
2331 term inPlaceDivideBy: count * (count + one). |
2289 count inPlaceAdd: two. |
2332 count inPlaceAdd: two. |
2290 sum inPlaceAdd: term. |
2333 sum inPlaceAdd: term. |
2291 term exponent + precBits < sum exponent] whileFalse. |
2334 term exponent + precBits < sum exponent] whileFalse. |
2292 ^sum |
2335 ^sum |
|
2336 |
|
2337 "Modified (comment): / 28-05-2019 / 17:44:30 / Claus Gittinger" |
2293 ! |
2338 ! |
2294 |
2339 |
2295 powerExpansionLnPrecision: precBits |
2340 powerExpansionLnPrecision: precBits |
2296 "Evaluate the neperian logarithm of the receiver by power series expansion. |
2341 "Evaluate the neperian logarithm of the receiver by power series expansion. |
2297 For quadratic convergence, use: |
2342 For quadratic convergence, use: |
2298 ln ((1+y)/(1-y)) = 2 y (1 + y^2/3 + y^4/5 + ... ) = 2 ar tanh( y ) |
2343 ln ((1+y)/(1-y)) = 2 y (1 + y^2/3 + y^4/5 + ... ) = 2 ar tanh( y ) |
2299 (1+y)/(1-y) = self => y = (self-1)/(self+1) |
2344 (1+y)/(1-y) = self => y = (self-1)/(self+1) |
2300 This algorithm is interesting when the receiver is close to 1" |
2345 This algorithm is interesting when the receiver is close to 1" |
2301 |
2346 |
2302 | one | |
2347 | one | |
2303 one _ self one. |
2348 one := self one. |
2304 ^((self - one)/(self + one) powerExpansionArTanhPrecision: precBits) timesTwoPower: 1 |
2349 ^((self - one)/(self + one) powerExpansionArTanhPrecision: precBits) timesTwoPower: 1 |
|
2350 |
|
2351 "Modified (comment): / 28-05-2019 / 17:44:38 / Claus Gittinger" |
2305 ! |
2352 ! |
2306 |
2353 |
2307 powerExpansionSinCosPrecision: precBits |
2354 powerExpansionSinCosPrecision: precBits |
2308 "Evaluate the sine and cosine of the receiver by power series expansion. |
2355 "Evaluate the sine and cosine of the receiver by power series expansion. |
2309 The algorithm is interesting when the receiver is close to zero" |
2356 The algorithm is interesting when the receiver is close to zero" |
2310 |
2357 |
2311 | count one sin cos term | |
2358 | count one sin cos term | |
2312 one _ self one. |
2359 one := self one. |
2313 count _ one copy. |
2360 count := one copy. |
2314 cos _ one copy. |
2361 cos := one copy. |
2315 sin _ self copy. |
2362 sin := self copy. |
2316 term _ self copy. |
2363 term := self copy. |
2317 |
2364 |
2318 [count inPlaceAdd: one. |
2365 [count inPlaceAdd: one. |
2319 term |
2366 term |
2320 inPlaceMultiplyBy: self; |
2367 inPlaceMultiplyBy: self; |
2321 inPlaceDivideBy: count; |
2368 inPlaceDivideBy: count; |
2322 inPlaceNegated. |
2369 inPlaceNegated. |
2323 cos inPlaceAdd: term. |
2370 cos inPlaceAdd: term. |
2324 |
2371 |
2325 count inPlaceAdd: one. |
2372 count inPlaceAdd: one. |
2326 term |
2373 term |
2327 inPlaceMultiplyBy: self; |
2374 inPlaceMultiplyBy: self; |
2328 inPlaceDivideBy: count. |
2375 inPlaceDivideBy: count. |
2329 sin inPlaceAdd: term. |
2376 sin inPlaceAdd: term. |
2330 |
2377 |
2331 term exponent + precBits < sin exponent] whileFalse. |
2378 term exponent + precBits < sin exponent] whileFalse. |
2332 ^Array with: sin with: cos |
2379 ^Array with: sin with: cos |
|
2380 |
|
2381 "Modified (comment): / 28-05-2019 / 17:44:43 / Claus Gittinger" |
2333 ! |
2382 ! |
2334 |
2383 |
2335 powerExpansionSinPrecision: precBits |
2384 powerExpansionSinPrecision: precBits |
2336 "Evaluate the sine of the receiver by power series expansion. |
2385 "Evaluate the sine of the receiver by power series expansion. |
2337 The algorithm is interesting when the receiver is close to zero" |
2386 The algorithm is interesting when the receiver is close to zero" |
2338 |
2387 |
2339 | count one sum term two x2 | |
2388 | count one sum term two x2 | |
2340 one _ self one. |
2389 one := self one. |
2341 two _ one timesTwoPower: 1. |
2390 two := one timesTwoPower: 1. |
2342 count _ two copy. |
2391 count := two copy. |
2343 sum _ self copy. |
2392 sum := self copy. |
2344 term _ self copy. |
2393 term := self copy. |
2345 x2 _ self squared. |
2394 x2 := self squared. |
2346 |
2395 |
2347 [term inPlaceMultiplyBy: x2. |
2396 [term inPlaceMultiplyBy: x2. |
2348 term inPlaceDivideBy: count * (count + one). |
2397 term inPlaceDivideBy: count * (count + one). |
2349 term inPlaceNegated. |
2398 term inPlaceNegated. |
2350 count inPlaceAdd: two. |
2399 count inPlaceAdd: two. |
2351 sum inPlaceAdd: term. |
2400 sum inPlaceAdd: term. |
2352 term exponent + precBits < sum exponent] whileFalse. |
2401 term exponent + precBits < sum exponent] whileFalse. |
2353 ^sum |
2402 ^sum |
|
2403 |
|
2404 "Modified (comment): / 28-05-2019 / 17:44:50 / Claus Gittinger" |
2354 ! |
2405 ! |
2355 |
2406 |
2356 powerExpansionSinhPrecision: precBits |
2407 powerExpansionSinhPrecision: precBits |
2357 "Evaluate the hyperbolic sine of the receiver by power series expansion. |
2408 "Evaluate the hyperbolic sine of the receiver by power series expansion. |
2358 The algorithm is interesting when the receiver is close to zero" |
2409 The algorithm is interesting when the receiver is close to zero" |
2359 |
2410 |
2360 | count one sum term two x2 | |
2411 | count one sum term two x2 | |
2361 one _ self one. |
2412 one := self one. |
2362 two _ one timesTwoPower: 1. |
2413 two := one timesTwoPower: 1. |
2363 count _ two copy. |
2414 count := two copy. |
2364 sum _ self copy. |
2415 sum := self copy. |
2365 term _ self copy. |
2416 term := self copy. |
2366 x2 _ self squared. |
2417 x2 := self squared. |
2367 |
2418 |
2368 [term inPlaceMultiplyBy: x2. |
2419 [term inPlaceMultiplyBy: x2. |
2369 term inPlaceDivideBy: count * (count + one). |
2420 term inPlaceDivideBy: count * (count + one). |
2370 count inPlaceAdd: two. |
2421 count inPlaceAdd: two. |
2371 sum inPlaceAdd: term. |
2422 sum inPlaceAdd: term. |
2372 term exponent + precBits < sum exponent] whileFalse. |
2423 term exponent + precBits < sum exponent] whileFalse. |
2373 ^sum |
2424 ^sum |
|
2425 |
|
2426 "Modified (comment): / 28-05-2019 / 17:44:56 / Claus Gittinger" |
2374 ! |
2427 ! |
2375 |
2428 |
2376 powerExpansionTanPrecision: precBits |
2429 powerExpansionTanPrecision: precBits |
2377 "Evaluate the tangent of the receiver by power series expansion. |
2430 "Evaluate the tangent of the receiver by power series expansion. |
2378 The algorithm is interesting when the receiver is close to zero" |
2431 The algorithm is interesting when the receiver is close to zero" |
2379 |
2432 |
2380 | count one sum term pow two x2 seidel | |
2433 | count one sum term pow two x2 seidel | |
2381 one _ self one. |
2434 one := self one. |
2382 two _ one timesTwoPower: 1. |
2435 two := one timesTwoPower: 1. |
2383 count _ two copy. |
2436 count := two copy. |
2384 sum _ one copy. |
2437 sum := one copy. |
2385 pow _ one copy. |
2438 pow := one copy. |
2386 x2 _ self squared. |
2439 x2 := self squared. |
2387 seidel _ OrderedCollection new: 256. |
2440 seidel := OrderedCollection new: 256. |
2388 seidel add: 1. |
2441 seidel add: 1. |
2389 |
2442 |
2390 [pow inPlaceMultiplyBy: x2. |
2443 [pow inPlaceMultiplyBy: x2. |
2391 pow inPlaceDivideBy: count * (count + one). |
2444 pow inPlaceDivideBy: count * (count + one). |
2392 count inPlaceAdd: two. |
2445 count inPlaceAdd: two. |
2393 2 to: seidel size do: [:i | seidel at: i put: (seidel at: i-1) + (seidel at: i)]. |
2446 2 to: seidel size do: [:i | seidel at: i put: (seidel at: i-1) + (seidel at: i)]. |
2394 seidel addLast: seidel last. |
2447 seidel addLast: seidel last. |
2395 seidel size to: 2 by: -1 do: [:i | seidel at: i - 1 put: (seidel at: i-1) + (seidel at: i)]. |
2448 seidel size to: 2 by: -1 do: [:i | seidel at: i - 1 put: (seidel at: i-1) + (seidel at: i)]. |
2396 seidel addFirst: seidel first. |
2449 seidel addFirst: seidel first. |
2397 term _ pow * seidel first. |
2450 term := pow * seidel first. |
2398 sum inPlaceAdd: term. |
2451 sum inPlaceAdd: term. |
2399 term exponent + precBits < sum exponent] whileFalse. |
2452 term exponent + precBits < sum exponent] whileFalse. |
2400 sum inPlaceMultiplyBy: self. |
2453 sum inPlaceMultiplyBy: self. |
2401 ^sum |
2454 ^sum |
|
2455 |
|
2456 "Modified (comment): / 28-05-2019 / 17:45:02 / Claus Gittinger" |
2402 ! |
2457 ! |
2403 |
2458 |
2404 powerExpansionTanhPrecision: precBits |
2459 powerExpansionTanhPrecision: precBits |
2405 "Evaluate the hyperbolic tangent of the receiver by power series expansion. |
2460 "Evaluate the hyperbolic tangent of the receiver by power series expansion. |
2406 The algorithm is interesting when the receiver is close to zero" |
2461 The algorithm is interesting when the receiver is close to zero" |
2407 |
2462 |
2408 | count one sum term pow two x2 seidel | |
2463 | count one sum term pow two x2 seidel | |
2409 one _ self one. |
2464 one := self one. |
2410 two _ one timesTwoPower: 1. |
2465 two := one timesTwoPower: 1. |
2411 count _ two copy. |
2466 count := two copy. |
2412 sum _ one copy. |
2467 sum := one copy. |
2413 pow _ one copy. |
2468 pow := one copy. |
2414 x2 _ self squared. |
2469 x2 := self squared. |
2415 seidel _ OrderedCollection new: 256. |
2470 seidel := OrderedCollection new: 256. |
2416 seidel add: 1. |
2471 seidel add: 1. |
2417 |
2472 |
2418 [pow inPlaceMultiplyBy: x2. |
2473 [pow inPlaceMultiplyBy: x2. |
2419 pow inPlaceDivideBy: count * (count + one). |
2474 pow inPlaceDivideBy: count * (count + one). |
2420 pow inPlaceNegated. |
2475 pow inPlaceNegated. |
2421 count inPlaceAdd: two. |
2476 count inPlaceAdd: two. |
2422 2 to: seidel size do: [:i | seidel at: i put: (seidel at: i-1) + (seidel at: i)]. |
2477 2 to: seidel size do: [:i | seidel at: i put: (seidel at: i-1) + (seidel at: i)]. |
2423 seidel addLast: seidel last. |
2478 seidel addLast: seidel last. |
2424 seidel size to: 2 by: -1 do: [:i | seidel at: i - 1 put: (seidel at: i-1) + (seidel at: i)]. |
2479 seidel size to: 2 by: -1 do: [:i | seidel at: i - 1 put: (seidel at: i-1) + (seidel at: i)]. |
2425 seidel addFirst: seidel first. |
2480 seidel addFirst: seidel first. |
2426 term _ pow * seidel first. |
2481 term := pow * seidel first. |
2427 sum inPlaceAdd: term. |
2482 sum inPlaceAdd: term. |
2428 term exponent + precBits < sum exponent] whileFalse. |
2483 term exponent + precBits < sum exponent] whileFalse. |
2429 sum inPlaceMultiplyBy: self. |
2484 sum inPlaceMultiplyBy: self. |
2430 ^sum |
2485 ^sum |
|
2486 |
|
2487 "Modified (comment): / 28-05-2019 / 17:45:07 / Claus Gittinger" |
2431 ! |
2488 ! |
2432 |
2489 |
2433 precision:precisionArg |
2490 precision:precisionArg |
2434 "set instance variables. |
2491 "set instance variables. |
2435 Notice, that the float's value is m * 2^e" |
2492 Notice, that the float's value is m * 2^e" |