Issue 4519 in pharo: -1 copySignTo: 0.0 should return Float negativeZero

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

Issue 4519 in pharo: -1 copySignTo: 0.0 should return Float negativeZero

pharo
Status: Accepted
Owner: [hidden email]
Labels: Type-Squeak

New issue 4519 by [hidden email]: -1 copySignTo: 0.0 should return  
Float negativeZero
http://code.google.com/p/pharo/issues/detail?id=4519

The original version I submitted in Squeak was ported in Pharo.
But my later correction did not...
More over, I cannot find a reference to copySignTo: in the issue tracker,  
though the methods obviously has been modified.

[ (-2 copySignTo: 0.0) sign = -1 ] assert.
[ (-2.0 copySignTo: 0.0) sign = -1 ] assert.

See:

Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-nice.571.mcz

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

Name: Kernel-nice.571
Author: nice
Time: 23 April 2011, 2:39:41.455 am
UUID: 2bd91b82-067a-49c9-a7a7-61771de27b3b
Ancestors: Kernel-nice.570

Connect the new DomainError
Correct (-1 copySignTo: 0.0) to return a negativeZero.
Add hyperbolic and inverse hyperbolic functions
Add plenty of Complex missing methods and few mathematical functions:
        i (multiply by 1 i)
        raisedTo:
        conjugated
        sqrt
        squaredNorm
        arcSin arcCos arcTan arcTan:
        sinh cosh tanh arSinh arCosh arTanh
Speed up a few complex functions by using #real:imaginary: directly rather  
than intermediate arithmetic operations.

=============== Diff against Kernel-nice.570 ===============

"I SNIPPED A LOT OF TRIGONOMETRIC/HYPERBOLIC DIFFS..."


Item was changed:
  ----- Method: Float>>arcSin (in category 'mathematical functions') -----
  arcSin
        "Answer the angle in radians."

+       ((self < -1.0) or: [self > 1.0]) ifTrue: [DomainError  
signal: 'arcSin only takes values between -1 and 1'].
-       ((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 changed:
  ----- Method: Float>>copySignTo: (in category 'mathematical functions')  
-----
  copySignTo: aNumber
        "Return a number with same magnitude as aNumber and same sign as  
self.
        Implementation note: take care of Float negativeZero, which is  
considered as having a negative sign."

+       (self > 0.0 or: [(self at: 1) = 0]) ifTrue: [^ aNumber abs].
+       ^aNumber withNegativeSign!
-       (self > 0 or: [(self at: 1) = 0])  ifTrue: [^ aNumber abs].
-       ^aNumber abs negated!


Item was changed:
  ----- Method: Float>>ln (in category 'mathematical functions') -----
  ln
        "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: [DomainError signal: 'ln is only defined for x  
> 0.0'].
-       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>>sqrt (in category 'mathematical functions') -----
  sqrt
        "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"
+                                       ^ DomainError signal: 'sqrt  
undefined for number less than zero.']].
-                                       ^ 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>>withNegativeSign (in category 'converting') -----
+ withNegativeSign
+       "Same as super, but handle the subtle case of Float negativeZero"
+
+       self = 0.0 ifTrue: [^self class negativeZero].
+       ^super withNegativeSign!

Item was changed:
  ----- Method: Fraction>>ln (in category 'mathematical functions') -----
  ln
        "This function is defined because super ln might overflow.
        Note that < 1 is tested before converting to float in order to avoid  
precision loss due to gradual underflow."
        | res int |
        self < 1 ifTrue: [^self reciprocal ln negated].
+       self <= 0 ifTrue: [DomainError signal: 'ln is only defined for x >  
0'].
-       self <= 0 ifTrue: [self error: 'ln is only defined for x > 0'].
        res := super ln.
        res isFinite ifTrue: [^res].
        int := self integerPart.
        ^int ln + (self / int) ln!

Item was changed:
  ----- Method: Fraction>>log (in category 'mathematical functions') -----
  log
        "This function is defined because super log might overflow.
        Note that < 1 is tested before converting to float in order to avoid  
precision loss due to gradual underflow."
        | res int |
        self < 1 ifTrue: [^self reciprocal log negated].
+       self <= 0 ifTrue: [DomainError signal: 'log is only defined for x >  
0'].
-       self <= 0 ifTrue: [self error: 'log is only defined for x > 0'].
        res := super log.
        res isFinite ifTrue: [^res].
        int := self integerPart.
        ^int log + (self / int) log!

Item was changed:
  ----- Method: Integer>>ln (in category 'mathematical functions') -----
  ln
        "This function is defined because super ln might overflow."
        | res h |
+       self <= 0 ifTrue: [DomainError signal: 'ln is only defined for x >  
0'].
-       self <= 0 ifTrue: [self error: 'ln is only defined for x > 0'].
        res := super ln.
        res isFinite ifTrue: [^res].
        h := self highBit.
        ^2 ln * h + (self / (1 << h)) asFloat ln!

Item was changed:
  ----- Method: Integer>>log (in category 'mathematical functions') -----
  log
        "This function is defined because super log might overflow."
        | res h |
+       self <= 0 ifTrue: [DomainError signal: 'log is only defined for x >  
0'].
-       self <= 0 ifTrue: [self error: 'log is only defined for x > 0'].
        res := super log.
        res isFinite ifTrue: [^res].
        h := self highBit.
        ^2 log * h + (self / (1 << h)) asFloat log!



Item was changed:
  ----- Method: Number>>copySignTo: (in category 'mathematical functions')  
-----
  copySignTo: aNumber
        "Return a number with same magnitude as aNumber and same sign as  
self."

        ^ self positive
                ifTrue: [aNumber abs]
+               ifFalse: [aNumber withNegativeSign].!
-               ifFalse: [aNumber abs negated].!



Item was added:
+ ----- Method: Number>>withNegativeSign (in category 'converting') -----
+ withNegativeSign
+       "Answer a number with same magnitude than receiver and negative  
sign."
+       ^self abs negated!




_______________________________________________
Pharo-bugtracker mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-bugtracker
Reply | Threaded
Open this post in threaded view
|

Re: Issue 4519 in pharo: -1 copySignTo: 0.0 should return Float negativeZero

pharo
Updates:
        Labels: Milestone-1.4

Comment #1 on issue 4519 by [hidden email]: -1 copySignTo: 0.0  
should return Float negativeZero
http://code.google.com/p/pharo/issues/detail?id=4519

Thanks! Sven will be happy to see you pushing fixes in Pharo :)


_______________________________________________
Pharo-bugtracker mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-bugtracker
Reply | Threaded
Open this post in threaded view
|

Re: Issue 4519 in pharo: -1 copySignTo: 0.0 should return Float negativeZero

pharo
Updates:
        Status: FixProposed

Comment #2 on issue 4519 by [hidden email]: -1 copySignTo: 0.0  
should return Float negativeZero
http://code.google.com/p/pharo/issues/detail?id=4519

See inbox, there is a SLICE


_______________________________________________
Pharo-bugtracker mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-bugtracker
Reply | Threaded
Open this post in threaded view
|

Re: Issue 4519 in pharo: -1 copySignTo: 0.0 should return Float negativeZero

pharo

Comment #3 on issue 4519 by [hidden email]: -1 copySignTo: 0.0  
should return Float negativeZero
http://code.google.com/p/pharo/issues/detail?id=4519

Tx!
One day we can reintroduce Complex if it makes sense.




_______________________________________________
Pharo-bugtracker mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-bugtracker
Reply | Threaded
Open this post in threaded view
|

Re: Issue 4519 in pharo: -1 copySignTo: 0.0 should return Float negativeZero

pharo
Updates:
        Status: Closed

Comment #4 on issue 4519 by [hidden email]: -1 copySignTo: 0.0  
should return Float negativeZero
http://code.google.com/p/pharo/issues/detail?id=4519

In 14036


_______________________________________________
Pharo-bugtracker mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-bugtracker