--- a/Number.st Thu May 05 06:48:19 2016 +0200
+++ b/Number.st Thu May 12 09:30:28 2016 +0200
@@ -1325,10 +1325,13 @@
cbrt
"return the cubic root of the receiver"
+ "/ 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 cbrt.
].
+ "/ very slow fallback
^ self cbrt_withAccuracy:self epsilon
!
@@ -1343,10 +1346,13 @@
exp
"compute e**x of the receiver"
+ "/ 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 exp.
].
+ "/ very slow fallback
^ self exp_withAccuracy:self epsilon
!
@@ -1368,10 +1374,13 @@
"return the natural logarithm of myself.
Raises an exception, if the receiver is less or equal to zero."
+ "/ 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 asLongFloat ln.
].
+ "/ very slow fallback
^ self ln_withAccuracy:self epsilon
"
@@ -1450,10 +1459,13 @@
sqrt
"return the square root of the receiver"
+ "/ 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 sqrt.
].
+ "/ very slow fallback
^ self sqrt_withAccuracy:self epsilon
!
@@ -2468,40 +2480,96 @@
arcCos
"return the arccosine of the receiver (in radians)"
+ "/ 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 arcCos.
].
+ "/ slow fallback
^ (self class pi / 2) - self arcSin
!
+arcCosech
+ "return the inverse hyperbolic cosecant of the receiver."
+ "caveat: misnomer; should be called aCosech or arCosech"
+
+ "/ 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 arcCosech.
+ ].
+ "/ slow fallback
+ ^ ((1 + ((self*self)+1) sqrt) / self) ln
+!
+
arcCosh
- "return the hyperbolic arccosine of the receiver."
-
+ "return the inverse hyperbolic cosine of the receiver."
+ "caveat: misnomer; should be called aCosh or arCosh"
+
+ "/ 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 arcCosh.
].
+ "/ slow fallback
^ (self + (self*self-1) sqrt) ln.
!
+arcCoth
+ "return the inverse hyperbolic cotangent of the receiver."
+ "caveat: misnomer; should be called aCoth or arCoth"
+
+ "/ 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 arcCoth.
+ ].
+ "/ slow fallback
+ ^ ((self+1) / (self-1)) ln / 2
+!
+
+arcSech
+ "return the inverse hyperbolic secant of the receiver."
+ "caveat: misnomer; should be called aSech or arSech"
+
+ "/ 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 arcSech.
+ ].
+ "/ slow fallback
+ ^ ((1 + (1-(self*self)) sqrt) / self) ln
+!
+
arcSin
"return the arcsine of the receiver (in radians)"
+ "/ 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 arcSin.
].
+ "/ very slow fallback
^ self arcSin_withAccuracy:self epsilon
!
arcSinh
- "return the hyperbolic arcsine of the receiver."
-
+ "return the inverse hyperbolic sine of the receiver."
+ "caveat: misnomer; should be called aSinh or arSinh"
+
+ "/ 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 arcSinh.
].
+ "/ slow fallback
^ ( self + (self*self+1) sqrt ) ln
"/ ^ self arcSinh_withAccuracy:self epsilon
!
@@ -2509,50 +2577,67 @@
arcTan
"return the arctangent of the receiver (as radians)"
+ "/ 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 arcTan.
].
+ "/ very slow fallback
^ self arcTan_withAccuracy:self epsilon
!
arcTan2:x
"return atan2(self,x) (as radians)"
+ "/ 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 arcTan2:x.
].
+ "/ very slow fallback
^ self arcTan2_withAccuracy:self epsilon x:x
!
arcTanh
- "return the hyperbolic arctangent of the receiver."
-
+ "return the inverse hyperbolic tangent of the receiver."
+ "caveat: misnomer; should be called aTanh or arTanh"
+
+ "/ 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 arcTanh.
].
- ^ ((self + 1) ln / 2) - ((1 - self) ln / 2)
+ "/ slow fallback
+ ^ ((1 + self) / (1 - self)) ln / 2
+ "/ s^ ((1 + self) ln / 2) - ((1 - self) ln / 2)
!
cos
"return the cosine of the receiver (interpreted as radians)"
+ "/ 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 cos.
].
+ "/ very slow fallback
^ self cos_withAccuracy:self epsilon
!
cosh
"return the hyperbolic cosine of the receiver"
+ "/ 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 cosh.
].
+ "/ very slow fallback
^ self cosh_withAccuracy:self epsilon
!
@@ -2565,6 +2650,8 @@
sin
"return the sine of the receiver (interpreted as radians)"
+ "/ 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 sin.
@@ -2575,6 +2662,8 @@
sinh
"return the hyperbolic sine of the receiver"
+ "/ 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 sinh.
@@ -2585,16 +2674,20 @@
tan
"return the tangens of the receiver (interpreted as radians)"
+ "/ slow fallback
^ self sin / self cos
!
tanh
"return the hyperbolic tangens of the receiver"
+ "/ 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.
].
+ "/ very slow fallback
^ self tanh_withAccuracy:self epsilon
"/ If a fast exp is available, the following might be better...