The Inbox: Kernel-mtf.527.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

The Inbox: Kernel-mtf.527.mcz

commits-2
Matthew Fulmer uploaded a new version of Kernel to project The Inbox:
http://source.squeak.org/inbox/Kernel-mtf.527.mcz

==================== Summary ====================

Name: Kernel-mtf.527
Author: mtf
Time: 13 December 2010, 5:03:32.48 pm
UUID: eee5f8ce-e738-4da7-bd87-64f50998fd53
Ancestors: Kernel-mtf.526

Use FloatMathPlugin for bit-identical floating point operations across machines. Needed by Croquet.

Cherrypicked from Croquet:

Name: Kernel-ar.16
Author: ar
Time: 26 March 2006, 7:01:20 pm
UUID: 99b21c76-119e-5440-aff8-02dfe0ecf377
Ancestors: Kernel-tmp.15

- use FloatMathPlugin primitives for Float

=============== Diff against Kernel-mtf.526 ===============

Item was changed:
  ----- Method: Float>>arcCos (in category 'mathematical functions') -----
  arcCos
  "Answer the angle in radians."
+ <primitive: 'primitiveArcCos' module: 'FloatMathPlugin'>
-
  ^ Halfpi - self arcSin!

Item was added:
+ ----- Method: Float>>arcCosH (in category 'mathematical functions') -----
+ arcCosH
+ <primitive: 'primitiveArcCosH' module: 'FloatMathPlugin'>
+ ^self primitiveFailed!

Item was changed:
  ----- Method: Float>>arcSin (in category 'mathematical functions') -----
  arcSin
  "Answer the angle in radians."
+ <primitive: 'primitiveArcSin' module: 'FloatMathPlugin'>
-
  ((self < -1.0) or: [self > 1.0]) ifTrue: [self error: 'Value out of range'].
  ((self = -1.0) or: [self = 1.0])
  ifTrue: [^ Halfpi * self]
  ifFalse: [^ (self / (1.0 - (self * self)) sqrt) arcTan]!

Item was added:
+ ----- Method: Float>>arcSinH (in category 'mathematical functions') -----
+ arcSinH
+ <primitive: 'primitiveArcSinH' module: 'FloatMathPlugin'>
+ ^self primitiveFailed!

Item was changed:
  ----- Method: Float>>arcTan (in category 'mathematical functions') -----
  arcTan
  "Answer the angle in radians.
  Optional. See Object documentation whatIsAPrimitive."
+ <primitive: 'primitiveArcTan' module: 'FloatMathPlugin'>
+ self = self ifFalse:[^self error: 'arcTan is undefined for NaN'].
-
- | theta eps step sinTheta cosTheta |
- <primitive: 57>
-
- "Newton-Raphson"
  self < 0.0 ifTrue: [ ^ 0.0 - (0.0 - self) arcTan ].
+ ^self primitiveArcTan!
-
- "first guess"
- theta := (self * Halfpi) / (self + 1.0).
-
- "iterate"
- eps := Halfpi * Epsilon.
- step := theta.
- [(step * step) > eps] whileTrue: [
- sinTheta := theta sin.
- cosTheta := theta cos.
- step := (sinTheta * cosTheta) - (self * cosTheta * cosTheta).
- theta := theta - step].
- ^ theta!

Item was changed:
  ----- Method: Float>>arcTan: (in category 'mathematical functions') -----
  arcTan: denominator
  "Answer the angle in radians.
+ Optional. See Object documentation whatIsAPrimitive."
+ | result |
+ <primitive: 'primitiveArcTan2' module: 'FloatMathPlugin'>
+ (self = 0.0) ifTrue: [
+ (denominator > 0.0)
+ ifTrue: [ result := 0 ]
+ ifFalse: [ result := Pi ]
+ ] ifFalse: [
+ (denominator = 0.0) ifTrue: [
+ (self > 0.0)
+ ifTrue: [ result := Halfpi ]
+ ifFalse: [ result := Halfpi negated ]
+ ] ifFalse: [
+ (denominator > 0)
+ ifTrue: [ result := (self / denominator) arcTan ]
+ ifFalse: [ result := ((self / denominator) arcTan) + Pi ]
+ ].
+ ].
+ ^ result.!
- Optional. See Object documentation whatIsAPrimitive.
- Implementation note: use sign in order to catch cases of negativeZero"
-
- ^self = 0.0
- ifTrue: [denominator sign >= 0
- ifTrue: [ 0 ]
- ifFalse: [ self sign >= 0
- ifTrue: [ Pi ]
- ifFalse: [ Pi negated ]]]
- ifFalse: [denominator = 0.0
- ifTrue: [self > 0.0
- ifTrue: [ Halfpi ]
- ifFalse: [ Halfpi negated ]]
- ifFalse: [denominator > 0
- ifTrue: [ (self / denominator) arcTan ]
- ifFalse: [self > 0
- ifTrue: [ ((self / denominator) arcTan) + Pi ]
- ifFalse: [ ((self / denominator) arcTan) - Pi ]]]]!

Item was added:
+ ----- Method: Float>>arcTanH (in category 'mathematical functions') -----
+ arcTanH
+ <primitive: 'primitiveArcTanH' module: 'FloatMathPlugin'>
+ ^self primitiveFailed!

Item was changed:
  ----- Method: Float>>cos (in category 'mathematical functions') -----
  cos
  "Answer the cosine of the receiver taken as an angle in radians."
+ <primitive: 'primitiveCos' module: 'FloatMathPlugin'>
+ self = self ifFalse:[^self error: 'cos is undefined for NaN'].
+ self abs = Float infinity ifTrue:[^self error: 'cos is undefined for Infinity'].
-
  ^ (self + Halfpi) sin!

Item was added:
+ ----- Method: Float>>cosH (in category 'mathematical functions') -----
+ cosH
+ "Answer the cosine of the receiver taken as an angle in radians."
+ <primitive: 'primitiveCosH' module: 'FloatMathPlugin'>
+ ^self primitiveFailed!

Item was changed:
  ----- Method: Float>>exp (in category 'mathematical functions') -----
  exp
  "Answer E raised to the receiver power.
  Optional. See Object documentation whatIsAPrimitive."
 
+ <primitive: 'primitiveExp' module: 'FloatMathPlugin'>
+ self = self ifFalse:[^self error: 'exp is undefined for NaN'].
+ "For now, fall back to the Squeak version of exp if FloatMathPlugin is absent"
+ ^self primitiveExp!
- | base fract correction delta div |
- <primitive: 59>
-
- "Taylor series"
- "check the special cases"
- self < 0.0 ifTrue: [^ (self negated exp) reciprocal].
- self = 0.0 ifTrue: [^ 1].
- self abs > MaxValLn ifTrue: [self error: 'exp overflow'].
-
- "get first approximation by raising e to integer power"
- base := E raisedToInteger: (self truncated).
-
- "now compute the correction with a short Taylor series"
- "fract will be 0..1, so correction will be 1..E"
- "in the worst case, convergance time is logarithmic with 1/Epsilon"
- fract := self fractionPart.
- fract = 0.0 ifTrue: [ ^ base ].  "no correction required"
-
- correction := 1.0 + fract.
- delta := fract * fract / 2.0.
- div := 2.0.
- [delta > Epsilon] whileTrue: [
- correction := correction + delta.
- div := div + 1.0.
- delta := delta * fract / div].
- correction := correction + delta.
- ^ base * correction!

Item was changed:
  ----- Method: Float>>fractionPart (in category 'truncation and round off') -----
  fractionPart
  "Primitive. Answer a Float whose value is the difference between the
  receiver and the receiver's asInteger value. Optional. See Object
  documentation whatIsAPrimitive."
+ <primitive: 'primitiveFractionalPart' module: 'FloatMathPlugin'>
-
- <primitive: 52>
  ^self - self truncated asFloat!

Item was added:
+ ----- Method: Float>>hypot: (in category 'mathematical functions') -----
+ hypot: arg
+ "hypot(x,y) returns sqrt(x^2+y^2) with error less  than 1 ulps"
+ <primitive: 'primitiveHypot' module: 'FloatMathPlugin'>
+ arg isFloat ifFalse:[^self hypot: arg asFloat].
+ ^self primitiveFailed!

Item was changed:
  ----- Method: Float>>ln (in category 'mathematical functions') -----
  ln
  "Answer the natural logarithm of the receiver.
  Optional. See Object documentation whatIsAPrimitive."
+ <primitive: 'primitiveLogN' module: 'FloatMathPlugin'>
+ self <= 0.0 ifTrue: [^self error: 'ln is only defined for x > 0.0'].
+ ^self primitiveLn!
-
- | expt n mant x div pow delta sum eps |
- <primitive: 58>
-
- "Taylor series"
- self <= 0.0 ifTrue: [self error: 'ln is only defined for x > 0.0'].
-
- "get a rough estimate from binary exponent"
- expt := self exponent.
- n := Ln2 * expt.
- mant := self timesTwoPower: 0 - expt.
-
- "compute fine correction from mantinssa in Taylor series"
- "mant is in the range [0..2]"
- "we unroll the loop to avoid use of abs"
- x := mant - 1.0.
- div := 1.0.
- pow := delta := sum := x.
- x := x negated.  "x <= 0"
- eps := Epsilon * (n abs + 1.0).
- [delta > eps] whileTrue: [
- "pass one: delta is positive"
- div := div + 1.0.
- pow := pow * x.
- delta := pow / div.
- sum := sum + delta.
- "pass two: delta is negative"
- div := div + 1.0.
- pow := pow * x.
- delta := pow / div.
- sum := sum + delta].
-
- ^ n + sum
-
- "2.718284 ln 1.0"!

Item was changed:
  ----- Method: Float>>log (in category 'mathematical functions') -----
  log
  "Answer the base 10 logarithm of the receiver."
+ <primitive: 'primitiveLog10' module: 'FloatMathPlugin'>
-
  ^ self ln / Ln10!

Item was added:
+ ----- Method: Float>>primitiveArcTan (in category 'primitives') -----
+ primitiveArcTan
+ "Answer the angle in radians.
+ Optional. See Object documentation whatIsAPrimitive."
+
+ | theta eps step sinTheta cosTheta |
+ <primitive: 57>
+
+ "Newton-Raphson"
+ self < 0.0 ifTrue: [ ^ 0.0 - (0.0 - self) arcTan ].
+
+ "first guess"
+ theta := (self * Halfpi) / (self + 1.0).
+
+ "iterate"
+ eps := Halfpi * Epsilon.
+ step := theta.
+ [(step * step) > eps] whileTrue: [
+ sinTheta := theta sin.
+ cosTheta := theta cos.
+ step := (sinTheta * cosTheta) - (self * cosTheta * cosTheta).
+ theta := theta - step].
+ ^ theta!

Item was added:
+ ----- Method: Float>>primitiveExp (in category 'primitives') -----
+ primitiveExp
+ "Answer E raised to the receiver power.
+ Optional. See Object documentation whatIsAPrimitive."
+
+ | base fract correction delta div |
+ <primitive: 59>
+
+ "Taylor series"
+ "check the special cases"
+ self < 0.0 ifTrue: [^ (self negated exp) reciprocal].
+ self = 0.0 ifTrue: [^ 1].
+ self abs > MaxValLn ifTrue: [self error: 'exp overflow'].
+
+ "get first approximation by raising e to integer power"
+ base := E raisedToInteger: (self truncated).
+
+ "now compute the correction with a short Taylor series"
+ "fract will be 0..1, so correction will be 1..E"
+ "in the worst case, convergance time is logarithmic with 1/Epsilon"
+ fract := self fractionPart.
+ fract = 0.0 ifTrue: [ ^ base ].  "no correction required"
+
+ correction := 1.0 + fract.
+ delta := fract * fract / 2.0.
+ div := 2.0.
+ [delta > Epsilon] whileTrue: [
+ correction := correction + delta.
+ div := div + 1.0.
+ delta := delta * fract / div].
+ correction := correction + delta.
+ ^ base * correction!

Item was added:
+ ----- Method: Float>>primitiveFractionPart (in category 'primitives') -----
+ primitiveFractionPart
+ "Primitive. Answer a Float whose value is the difference between the
+ receiver and the receiver's asInteger value. Optional. See Object
+ documentation whatIsAPrimitive."
+
+ <primitive: 52>
+ ^self - self truncated asFloat!

Item was added:
+ ----- Method: Float>>primitiveLn (in category 'primitives') -----
+ primitiveLn
+ "Answer the natural logarithm of the receiver.
+ Optional. See Object documentation whatIsAPrimitive."
+
+ | expt n mant x div pow delta sum eps |
+ <primitive: 58>
+
+ "Taylor series"
+ self <= 0.0 ifTrue: [self error: 'ln is only defined for x > 0.0'].
+
+ "get a rough estimate from binary exponent"
+ expt := self exponent.
+ n := Ln2 * expt.
+ mant := self timesTwoPower: 0 - expt.
+
+ "compute fine correction from mantinssa in Taylor series"
+ "mant is in the range [0..2]"
+ "we unroll the loop to avoid use of abs"
+ x := mant - 1.0.
+ div := 1.0.
+ pow := delta := sum := x.
+ x := x negated.  "x <= 0"
+ eps := Epsilon * (n abs + 1.0).
+ [delta > eps] whileTrue: [
+ "pass one: delta is positive"
+ div := div + 1.0.
+ pow := pow * x.
+ delta := pow / div.
+ sum := sum + delta.
+ "pass two: delta is negative"
+ div := div + 1.0.
+ pow := pow * x.
+ delta := pow / div.
+ sum := sum + delta].
+
+ ^ n + sum
+
+ "2.718284 ln 1.0"!

Item was added:
+ ----- Method: Float>>primitiveSin (in category 'primitives') -----
+ primitiveSin
+ "Answer the sine of the receiver taken as an angle in radians.
+ Optional. See Object documentation whatIsAPrimitive."
+
+ | sum delta self2 i |
+ <primitive: 56>
+
+ "Taylor series"
+ "normalize to the range [0..Pi/2]"
+ self < 0.0 ifTrue: [^ (0.0 - ((0.0 - self) sin))].
+ self > Twopi ifTrue: [^ (self \\ Twopi) sin].
+ self > Pi ifTrue: [^ (0.0 - (self - Pi) sin)].
+ self > Halfpi ifTrue: [^ (Pi - self) sin].
+
+ "unroll loop to avoid use of abs"
+ sum := delta := self.
+ self2 := 0.0 - (self * self).
+ i := 2.0.
+ [delta > Epsilon] whileTrue: [
+ "once"
+ delta := (delta * self2) / (i * (i + 1.0)).
+ i := i + 2.0.
+ sum := sum + delta.
+ "twice"
+ delta := (delta * self2) / (i * (i + 1.0)).
+ i := i + 2.0.
+ sum := sum + delta].
+ ^ sum!

Item was added:
+ ----- Method: Float>>primitiveSqrt (in category 'primitives') -----
+ primitiveSqrt
+ "Answer the square root of the receiver.
+ Optional. See Object documentation whatIsAPrimitive."
+ | exp guess eps delta |
+ <primitive: 55>
+ #Numeric.
+ "Changed 200/01/19 For ANSI <number> support."
+ "Newton-Raphson"
+ self <= 0.0
+ ifTrue: [self = 0.0
+ ifTrue: [^ 0.0]
+ ifFalse: ["v Chg"
+ ^ FloatingPointException signal: 'undefined if less than zero.']].
+ "first guess is half the exponent"
+ exp := self exponent // 2.
+ guess := self timesTwoPower: 0 - exp.
+ "get eps value"
+ eps := guess * Epsilon.
+ eps := eps * eps.
+ delta := self - (guess * guess) / (guess * 2.0).
+ [delta * delta > eps]
+ whileTrue:
+ [guess := guess + delta.
+ delta := self - (guess * guess) / (guess * 2.0)].
+ ^ guess!

Item was added:
+ ----- Method: Float>>primitiveTimesTwoPower: (in category 'primitives') -----
+ primitiveTimesTwoPower: anInteger
+ "Primitive. Answer with the receiver multiplied by 2.0 raised
+ to the power of the argument.
+ Optional. See Object documentation whatIsAPrimitive."
+
+ <primitive: 54>
+
+ anInteger < -29 ifTrue: [^ self * (2.0 raisedToInteger: anInteger)].
+ anInteger < 0 ifTrue: [^ self / (1 bitShift: (0 - anInteger)) asFloat].
+ anInteger < 30 ifTrue: [^ self * (1 bitShift: anInteger) asFloat].
+ ^ self * (2.0 raisedToInteger: anInteger)!

Item was changed:
  ----- Method: Float>>sin (in category 'mathematical functions') -----
  sin
  "Answer the sine of the receiver taken as an angle in radians.
  Optional. See Object documentation whatIsAPrimitive."
+ <primitive: 'primitiveSin' module: 'FloatMathPlugin'>
+ self = self ifFalse:[^self error: 'sin is undefined for NaN'].
+ self abs = Float infinity ifTrue:[^self error: 'sin is undefined for Infinity'].
+ ^self primitiveSin!
-
- | sum delta self2 i |
- <primitive: 56>
-
- "Taylor series"
- "normalize to the range [0..Pi/2]"
- self < 0.0 ifTrue: [^ (0.0 - ((0.0 - self) sin))].
- self > Twopi ifTrue: [^ (self \\ Twopi) sin].
- self > Pi ifTrue: [^ (0.0 - (self - Pi) sin)].
- self > Halfpi ifTrue: [^ (Pi - self) sin].
-
- "unroll loop to avoid use of abs"
- sum := delta := self.
- self2 := 0.0 - (self * self).
- i := 2.0.
- [delta > Epsilon] whileTrue: [
- "once"
- delta := (delta * self2) / (i * (i + 1.0)).
- i := i + 2.0.
- sum := sum + delta.
- "twice"
- delta := (delta * self2) / (i * (i + 1.0)).
- i := i + 2.0.
- sum := sum + delta].
- ^ sum!

Item was added:
+ ----- Method: Float>>sinH (in category 'mathematical functions') -----
+ sinH
+ <primitive: 'primitiveSinH' module: 'FloatMathPlugin'>
+ ^self primitiveFailed!

Item was changed:
  ----- Method: Float>>sqrt (in category 'mathematical functions') -----
  sqrt
  "Answer the square root of the receiver.
  Optional. See Object documentation whatIsAPrimitive."
+
+ "ar 3/26/2006: sqrt is the ONE primitive that we really don't want to use from FloatMathPlugin - it's several times slower and we use it often enough that this can make a noticable difference"
+
+ <primitive: 55> "instead of: <primitive: 'primitiveSqrt' module: 'FloatMathPlugin'>"
+ ^self primitiveSqrt!
- | exp guess eps delta |
- <primitive: 55>
- #Numeric.
- "Changed 200/01/19 For ANSI <number> support."
- "Newton-Raphson"
- self <= 0.0
- ifTrue: [self = 0.0
- ifTrue: [^ 0.0]
- ifFalse: ["v Chg"
- ^ FloatingPointException signal: 'undefined if less than zero.']].
- "first guess is half the exponent"
- exp := self exponent // 2.
- guess := self timesTwoPower: 0 - exp.
- "get eps value"
- eps := guess * Epsilon.
- eps := eps * eps.
- delta := self - (guess * guess) / (guess * 2.0).
- [delta * delta > eps]
- whileTrue:
- [guess := guess + delta.
- delta := self - (guess * guess) / (guess * 2.0)].
- ^ guess!

Item was changed:
  ----- Method: Float>>tan (in category 'mathematical functions') -----
  tan
  "Answer the tangent of the receiver taken as an angle in radians."
+ <primitive: 'primitiveTan' module: 'FloatMathPlugin'>
+ self = self ifFalse:[^self error: 'tan is undefined for NaN'].
-
  ^ self sin / self cos!

Item was added:
+ ----- Method: Float>>tanH (in category 'mathematical functions') -----
+ tanH
+ <primitive: 'primitiveTanH' module: 'FloatMathPlugin'>
+ ^self primitiveFailed!

Item was changed:
  ----- Method: Float>>timesTwoPower: (in category 'mathematical functions') -----
  timesTwoPower: anInteger
  "Primitive. Answer with the receiver multiplied by 2.0 raised
  to the power of the argument.
  Optional. See Object documentation whatIsAPrimitive."
+ <primitive: 'primitiveTimesTwoPower' module: 'FloatMathPlugin'>
+ ^self primitiveTimesTwoPower: anInteger!
-
- <primitive: 54>
-
- anInteger < -29 ifTrue: [^ self * (2.0 raisedToInteger: anInteger)].
- anInteger < 0 ifTrue: [^ self / (1 bitShift: (0 - anInteger)) asFloat].
- anInteger < 30 ifTrue: [^ self * (1 bitShift: anInteger) asFloat].
- ^ self * (2.0 raisedToInteger: anInteger)!

Item was added:
+ ----- Method: Number>>hypot: (in category 'mathematical functions') -----
+ hypot: arg
+ "hypot(x,y) returns sqrt(x^2+y^2) with error less  than 1 ulps"
+ ^self asFloat hypot: arg asFloat!