#BUGFIX by cg
class: IEEEFloat
comment/format in: #equalFromIEEEFloat:
changed: #lessFromIEEEFloat:
--- a/IEEEFloat.st Thu Dec 05 14:48:44 2019 +0100
+++ b/IEEEFloat.st Thu Dec 05 15:02:09 2019 +0100
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
"{ Package: 'stx:libbasic2' }"
"{ NameSpace: Smalltalk }"
@@ -405,6 +407,7 @@
1 to:nBytes-1 do:[:i |
(self basicAt:i) = (anIEEEFloat basicAt:i) ifFalse:[^ false].
].
+ "/ care for negative zero
(self basicAt:nBytes) = (anIEEEFloat basicAt:nBytes) ifFalse:[
((self basicAt:nBytes) bitAnd:16r7F) == 0 ifTrue:[
((anIEEEFloat basicAt:nBytes) bitAnd:16r7F) == 0 ifTrue:[
@@ -447,18 +450,38 @@
!
lessFromIEEEFloat:anIEEEFloat
- |m1 m2 nM1 nM2 e1 e2|
+ |m1 m2 nM1 nM2 e1 e2 meNegative mySize myByte otherByte isLess|
- self negative = anIEEEFloat negative ifFalse:[
+ meNegative := self negative.
+ meNegative = anIEEEFloat negative ifFalse:[
^ anIEEEFloat negative
].
- anIEEEFloat basicSize == self basicSize ifTrue:[
+ "/ same sized floats can be compared easily
+ "/ (but care for the negative 0)
+ mySize := self basicSize.
+ mySize == anIEEEFloat basicSize ifTrue:[
anIEEEFloat exponentSize == exponentSize ifTrue:[
- self basicSize to:1 by:-1 do:[:i |
- (anIEEEFloat basicAt:i) < (self basicAt:i) ifTrue:[^ true].
- (anIEEEFloat basicAt:i) > (self basicAt:i) ifTrue:[^ false].
+ "/ ignore the sign bit
+ myByte := (self basicAt:mySize) bitAnd:16r7F.
+ otherByte := (anIEEEFloat basicAt:mySize) bitAnd:16r7F.
+ otherByte < myByte ifTrue:[
+ ^ meNegative not
+ ].
+ otherByte > myByte ifTrue:[
+ ^ meNegative
].
+ mySize-1 to:1 by:-1 do:[:i |
+ myByte := self basicAt:i.
+ otherByte := anIEEEFloat basicAt:i.
+ otherByte < myByte ifTrue:[
+ ^ meNegative not
+ ].
+ otherByte > myByte ifTrue:[
+ ^ meNegative
+ ].
+ ].
+ "/ same
^ false.
].
].
@@ -482,8 +505,31 @@
e1 := anIEEEFloat exponent.
e2 := self exponent.
- e1 = e2 ifTrue:[^ m1 < m2].
- ^ e1 < e2.
+ isLess := e1 = e2 ifTrue:[m1 < m2] ifFalse:[e1 < e2].
+ meNegative ifTrue:[^ isLess not].
+ ^ isLess.
+
+ "
+ self assert:(1.0 asIEEEFloat < 2.0 asIEEEFloat).
+ self assert:(1.0 asIEEEFloat < 1.0 asIEEEFloat) not.
+ self assert:(1.0 asIEEEFloat < 0.0 asIEEEFloat) not.
+ self assert:(1.0 asIEEEFloat < -0.0 asIEEEFloat) not.
+
+ self assert:(-1.0 asIEEEFloat < 2.0 asIEEEFloat).
+ self assert:(-1.0 asIEEEFloat < 1.0 asIEEEFloat).
+ self assert:(-1.0 asIEEEFloat < 0.0 asIEEEFloat).
+ self assert:(-1.0 asIEEEFloat < -0.0 asIEEEFloat).
+
+ self assert:(1.0 asIEEEFloat < -2.0 asIEEEFloat) not.
+ self assert:(1.0 asIEEEFloat < -1.0 asIEEEFloat) not.
+ self assert:(1.0 asIEEEFloat < 0.0 asIEEEFloat) not.
+ self assert:(1.0 asIEEEFloat < -0.0 asIEEEFloat) not.
+
+ self assert:(-1.0 asIEEEFloat < -2.0 asIEEEFloat) not.
+ self assert:(-1.0 asIEEEFloat < -1.0 asIEEEFloat) not.
+ self assert:(-1.0 asIEEEFloat < 0.0 asIEEEFloat).
+ self assert:(-1.0 asIEEEFloat < -0.0 asIEEEFloat).
+ "
!
productFromIEEEFloat:anIEEEFloat