--- a/Number.st Wed Jul 05 17:00:20 2017 +0200
+++ b/Number.st Wed Jul 05 17:41:24 2017 +0200
@@ -1505,10 +1505,16 @@
"/ retry after converting to float
(self isLimitedPrecisionReal not
or:[self generality < 1.0 generality]) ifTrue:[
- ^ self asFloat cbrt.
+ |f|
+
+ (f := self asLongFloat) isFinite ifTrue:[
+ ^ f cbrt.
+ ].
].
"/ very slow fallback
^ self cbrt_withAccuracy:self epsilon
+
+ "Modified: / 05-07-2017 / 17:23:27 / cg"
!
conjugated
@@ -1526,12 +1532,16 @@
"/ retry after converting to float
(self isLimitedPrecisionReal not
or:[self generality < 1.0 generality]) ifTrue:[
- ^ self asFloat exp.
+ |f|
+
+ (f := self asLongFloat) isFinite ifTrue:[
+ ^ f exp.
+ ].
].
"/ very slow fallback
^ self exp_withAccuracy:self epsilon
- "Modified: / 22-06-2017 / 16:57:32 / cg"
+ "Modified: / 05-07-2017 / 17:23:36 / cg"
!
floorLog:radix
@@ -1565,7 +1575,11 @@
"/ retry after converting to float
(self isLimitedPrecisionReal not
or:[self generality < 1.0 generality]) ifTrue:[
- ^ self asLongFloat ln.
+ |f|
+
+ (f := self asLongFloat) isFinite ifTrue:[
+ ^ f ln.
+ ].
].
"/ very slow fallback
^ self ln_withAccuracy:self epsilon
@@ -1574,7 +1588,7 @@
(10 raisedTo:1000) ln
"
- "Modified (comment): / 18-06-2017 / 23:31:57 / cg"
+ "Modified: / 05-07-2017 / 17:23:50 / cg"
!
log
@@ -1591,7 +1605,11 @@
(self isLimitedPrecisionReal not
or:[self generality < 1.0 generality]) ifTrue:[
- ^ self asLongFloat log10.
+ |f|
+
+ (f := self asLongFloat) isFinite ifTrue:[
+ ^ f log10.
+ ].
].
^ self ln / self class ln10
@@ -1602,7 +1620,7 @@
(10 raisedTo:8000) log10
"
- "Modified (comment): / 16-06-2017 / 11:06:15 / cg"
+ "Modified: / 05-07-2017 / 17:23:06 / cg"
!
log:aNumber
@@ -1659,10 +1677,16 @@
"/ retry after converting to float
(self isLimitedPrecisionReal not
or:[self generality < 1.0 generality]) ifTrue:[
- ^ self asFloat sqrt.
+ |f|
+
+ (f := self asLongFloat) isFinite ifTrue:[
+ ^ f sqrt.
+ ].
].
"/ very slow fallback
^ self sqrt_withAccuracy:self epsilon
+
+ "Modified: / 05-07-2017 / 17:24:11 / cg"
!
sqrtWithErrorLessThan:epsilon
@@ -2368,8 +2392,8 @@
y := (self - 1)/(self + 1).
exp := y2 := y squared.
- approx := 1.
- denominator := 3.
+ approx := 1.0.
+ denominator := 3.0.
count := 1.
[
@@ -2417,7 +2441,7 @@
0.69314718055994530941723212145817656807550013436025525412068000949339362196969471560586332699641868754200148102057068573368552023575813055703267075163507596193072757082837143519030703862389167347112335 01153644979552391204751726...
"
- "Modified (comment): / 03-07-2017 / 18:37:57 / cg"
+ "Modified: / 05-07-2017 / 17:16:24 / cg"
!
nthRoot:n withAccuracy:epsilon
@@ -2867,10 +2891,16 @@
"/ retry after converting to float
(self isLimitedPrecisionReal not
or:[self generality < 1.0 generality]) ifTrue:[
- ^ self asFloat arcCos.
+ |f|
+
+ (f := self asLongFloat) isFinite ifTrue:[
+ ^ f arcCos.
+ ].
].
"/ slow fallback
^ (self class pi / 2) - self arcSin
+
+ "Modified: / 05-07-2017 / 17:24:32 / cg"
!
arcCosech
@@ -2881,10 +2911,16 @@
"/ retry after converting to float
(self isLimitedPrecisionReal not
or:[self generality < 1.0 generality]) ifTrue:[
- ^ self asFloat arcCosech.
+ |f|
+
+ (f := self asLongFloat) isFinite ifTrue:[
+ ^ f arcCosech.
+ ].
].
"/ slow fallback
^ ((1 + ((self*self)+1) sqrt) / self) ln
+
+ "Modified: / 05-07-2017 / 17:24:56 / cg"
!
arcCosh
@@ -2895,10 +2931,16 @@
"/ retry after converting to float
(self isLimitedPrecisionReal not
or:[self generality < 1.0 generality]) ifTrue:[
- ^ self asFloat arcCosh.
+ |f|
+
+ (f := self asLongFloat) isFinite ifTrue:[
+ ^ f arcCosh.
+ ].
].
"/ slow fallback
^ (self + (self*self-1) sqrt) ln.
+
+ "Modified: / 05-07-2017 / 17:25:03 / cg"
!
arcCoth
@@ -2909,10 +2951,16 @@
"/ retry after converting to float
(self isLimitedPrecisionReal not
or:[self generality < 1.0 generality]) ifTrue:[
- ^ self asFloat arcCoth.
+ |f|
+
+ (f := self asLongFloat) isFinite ifTrue:[
+ ^ f arcCoth.
+ ].
].
"/ slow fallback
^ ((self+1) / (self-1)) ln / 2
+
+ "Modified: / 05-07-2017 / 17:25:14 / cg"
!
arcSech
@@ -2923,10 +2971,16 @@
"/ retry after converting to float
(self isLimitedPrecisionReal not
or:[self generality < 1.0 generality]) ifTrue:[
- ^ self asFloat arcSech.
+ |f|
+
+ (f := self asLongFloat) isFinite ifTrue:[
+ ^ f arcSech.
+ ].
].
"/ slow fallback
^ ((1 + (1-(self*self)) sqrt) / self) ln
+
+ "Modified: / 05-07-2017 / 17:25:22 / cg"
!
arcSin
@@ -2936,10 +2990,16 @@
"/ retry after converting to float
(self isLimitedPrecisionReal not
or:[self generality < 1.0 generality]) ifTrue:[
- ^ self asFloat arcSin.
+ |f|
+
+ (f := self asLongFloat) isFinite ifTrue:[
+ ^ f arcSin.
+ ].
].
"/ very slow fallback
^ self arcSin_withAccuracy:self epsilon
+
+ "Modified: / 05-07-2017 / 17:25:30 / cg"
!
arcSinh
@@ -2950,11 +3010,17 @@
"/ retry after converting to float
(self isLimitedPrecisionReal not
or:[self generality < 1.0 generality]) ifTrue:[
- ^ self asFloat arcSinh.
+ |f|
+
+ (f := self asLongFloat) isFinite ifTrue:[
+ ^ f arcSinh.
+ ].
].
"/ slow fallback
^ ( self + (self*self+1) sqrt ) ln
"/ ^ self arcSinh_withAccuracy:self epsilon
+
+ "Modified: / 05-07-2017 / 17:25:38 / cg"
!
arcTan
@@ -2964,10 +3030,16 @@
"/ retry after converting to float
(self isLimitedPrecisionReal not
or:[self generality < 1.0 generality]) ifTrue:[
- ^ self asFloat arcTan.
+ |f|
+
+ (f := self asLongFloat) isFinite ifTrue:[
+ ^ f arcTan.
+ ].
].
"/ very slow fallback
^ self arcTan_withAccuracy:self epsilon
+
+ "Modified: / 05-07-2017 / 17:25:46 / cg"
!
arcTan2:x
@@ -2977,10 +3049,16 @@
"/ retry after converting to float
(self isLimitedPrecisionReal not
or:[self generality < 1.0 generality]) ifTrue:[
- ^ self asFloat arcTan2:x.
+ |f|
+
+ (f := self asFloat) isFinite ifTrue:[
+ ^ f arcTan2:x.
+ ].
].
"/ very slow fallback
^ self arcTan2_withAccuracy:self epsilon x:x
+
+ "Modified: / 05-07-2017 / 17:26:16 / cg"
!
arcTanh
@@ -2991,11 +3069,17 @@
"/ retry after converting to float
(self isLimitedPrecisionReal not
or:[self generality < 1.0 generality]) ifTrue:[
- ^ self asFloat arcTanh.
+ |f|
+
+ (f := self asLongFloat) isFinite ifTrue:[
+ ^ f arcTanh.
+ ].
].
"/ slow fallback
^ ((1 + self) / (1 - self)) ln / 2
"/ s^ ((1 + self) ln / 2) - ((1 - self) ln / 2)
+
+ "Modified: / 05-07-2017 / 17:26:27 / cg"
!
cos
@@ -3005,10 +3089,16 @@
"/ retry after converting to float
(self isLimitedPrecisionReal not
or:[self generality < 1.0 generality]) ifTrue:[
- ^ self asFloat cos.
+ |f|
+
+ (f := self asLongFloat) isFinite ifTrue:[
+ ^ f cos.
+ ].
].
"/ very slow fallback
^ self cos_withAccuracy:self epsilon
+
+ "Modified: / 05-07-2017 / 17:26:33 / cg"
!
cosh
@@ -3018,10 +3108,16 @@
"/ retry after converting to float
(self isLimitedPrecisionReal not
or:[self generality < 1.0 generality]) ifTrue:[
- ^ self asFloat cosh.
+ |f|
+
+ (f := self asLongFloat) isFinite ifTrue:[
+ ^ f cosh.
+ ].
].
"/ very slow fallback
^ self cosh_withAccuracy:self epsilon
+
+ "Modified: / 05-07-2017 / 17:26:39 / cg"
!
cot
@@ -3037,9 +3133,15 @@
"/ retry after converting to float
(self isLimitedPrecisionReal not
or:[self generality < 1.0 generality]) ifTrue:[
- ^ self asFloat sin.
+ |f|
+
+ (f := self asLongFloat) isFinite ifTrue:[
+ ^ f sin.
+ ].
].
^ self sin_withAccuracy:self epsilon
+
+ "Modified: / 05-07-2017 / 17:26:47 / cg"
!
sinh
@@ -3049,9 +3151,20 @@
"/ retry after converting to float
(self isLimitedPrecisionReal not
or:[self generality < 1.0 generality]) ifTrue:[
- ^ self asFloat sinh.
+ |f|
+
+ (f := self asLongFloat) isFinite ifTrue:[
+ ^ f sinh.
+ ].
].
^ self sinh_withAccuracy:self epsilon
+
+ "
+ 10 sinh -> 11013.23287470339338
+ (10 exp - (-10 exp)) / 2 -> 11013.23287470339338
+ "
+
+ "Modified (comment): / 05-07-2017 / 17:32:27 / cg"
!
tan
@@ -3064,33 +3177,41 @@
tanh
"return the hyperbolic tangens of the receiver"
+ "/ tanh is:
+ "/ sinh(x)
+ "/ -------
+ "/ cosh(x)
+ "/
+ "/ which is:
+ "/ (exp(x) - exp(-x)) / 2
+ "/ ----------------------
+ "/ (exp(x) + exp(-x)) / 2
+
+ |exp nexp|
+
"/ if I am not a Float (or a less general lpReal),
"/ retry after converting to float
(self isLimitedPrecisionReal not
or:[self generality < 1.0 generality]) ifTrue:[
- ^ self asFloat tanh.
+ |f|
+
+ (f := self asLongFloat) isFinite ifTrue:[
+ ^ f tanh.
+ ].
].
+
"/ very slow fallback
- ^ self tanh_withAccuracy:self epsilon
-
-"/ If a fast exp is available, the following might be better...
-"/
-"/ |exp nexp|
-"/
-"/ "/ tanh is:
-"/ "/ sinh(x)
-"/ "/ -------
-"/ "/ cosh(x)
-"/ "/
-"/ "/ which is:
-"/ "/ (exp(x) - exp(-x)) / 2
-"/ "/ ----------------------
-"/ "/ (exp(x) + exp(-x)) / 2
-"/
-"/ exp := self exp.
-"/ nexp := self negated exp.
-"/
-"/ ^ (exp - nexp) / (exp + nexp)
+ "/ assuming that if we arrive here, the stuff is taylor computed manually anyway,
+ "/ the question is if taylor-for-exp converges faster than tailor-for-sin/cos
+ "/ So it may be faster to:
+ "/ ^ self sinh / self cosh
+
+ exp := self exp.
+ nexp := self negated exp.
+
+ ^ (exp - nexp) / (exp + nexp)
+
+ "Modified (comment): / 05-07-2017 / 17:34:59 / cg"
! !
!Number methodsFor:'truncation & rounding'!