[Glass] Negative infinity and positive infinity have the same sign

Tobias Pape via Glass glass at lists.gemtalksystems.com
Fri Jan 27 13:02:21 PST 2017


Hi All,

I brought this up to squeak-dev, as this bug happens in Squeak, too.

Here is what Nicolas Cellier just pushed to Squeak Trunk, hope that helps.

Begin forwarded message:

> From: commits at source.squeak.org
> Subject: [squeak-dev] The Trunk: Kernel-nice.1054.mcz
> Date: 27. Januar 2017 21:45:16 MEZ
> To: squeak-dev at lists.squeakfoundation.org, packages at lists.squeakfoundation.org
> Reply-To: squeak-dev at lists.squeakfoundation.org
> Delivered-To: squeak-dev at mail.squeak.org
> 
> Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
> http://source.squeak.org/trunk/Kernel-nice.1054.mcz
> 
> ==================== Summary ====================
> 
> Name: Kernel-nice.1054
> Author: nice
> Time: 27 January 2017, 9:44:46.83377 pm
> UUID: ef21d74d-ba81-47c6-9bb7-92fb4140f494
> Ancestors: Kernel-eem.1053
> 
> Change -0.0 sign to answer 0 instead of -1.
> Introduce a new message signBit for recognition of Float negativeZero.
> 
> Rationale:
> 1) The value of Float negativeZero cannot be distinguished from zero.
>   Thus (Float negativeZero = 0.0)
>   We can then expect sign to be symmetric for (positive) zero and negativeZero
> 2) ANSI Smalltalk requires above behavior.
>   This will reduce un-necessary difference with Gemstone for example.
> 
> About NaN:
> Note that with old implementation, the sign of "positive" nan was 0, while it was -1 for "negative" nan.
> New implementation will allways answer 0 for nans.
> 
> We may as well answer Float nan, but currently sign will allways answer an Integer (-1,0 or 1). Until it is well specified by a standard, let's not bother.
> Otherwise, we could answer a Float if receiver is a Float like:
> 
> sign
> 	self > 0.0 ifTrue: [ ^1.0].
> 	self < 0.0 ifTrue: [ ^-1.0].
> 	^self
> 
> =============== Diff against Kernel-eem.1053 ===============
> 
> Item was changed:
>  ----- Method: Float>>arcTan: (in category 'mathematical functions') -----
>  arcTan: denominator
> + 	"Answer the angle in radians, taking care of 4 quadrants.
> + 	Implementation note: use signBit and sign: in order to catch cases of negativeZero"
> - 	"Answer the angle in radians.
> - 	 Optional. See Object documentation whatIsAPrimitive.
> - 	Implementation note: use sign in order to catch cases of negativeZero"
> 
> + 	self = 0.0
> + 		ifTrue:
> + 			[denominator signBit = 0 ifTrue: [ ^0.0 ].
> + 			^Pi sign: self ].
> + 	denominator = 0.0 ifTrue: [ ^Halfpi sign: self ].
> + 	denominator > 0.0 	ifTrue: [ ^(self / denominator) arcTan ].
> + 	^(self / denominator) arcTan + (Pi sign: self)!
> - 	self = 0.0 ifTrue: [
> - 		denominator sign >= 0 ifTrue: [ ^0.0 ].
> - 		self sign >= 0 ifTrue: [ ^Pi ].
> - 		^0.0 - Pi ].
> - 	denominator = 0.0 ifTrue: [
> - 		self > 0.0 ifTrue: [ ^Halfpi ].
> - 		^0.0 - Halfpi ].
> - 	denominator > 0.0 	ifTrue: [  ^(self / denominator) arcTan ].
> - 	self > 0.0 ifTrue: [ ^(self / denominator) arcTan + Pi ].
> - 	^(self / denominator) arcTan - Pi!
> 
> Item was changed:
>  ----- Method: Float>>byteEncode:base: (in category 'printing') -----
>  byteEncode: aStream base: base
>  	"Handle sign, zero, and NaNs; all other values passed to absPrintOn:base:" 
> 
>  	self isNaN ifTrue: [aStream print: 'NaN'. ^ self]. "check for NaN before sign"
>  	self > 0.0
>  		ifTrue: [self absByteEncode: aStream base: base]
>  		ifFalse:
> + 			[self signBit = 1
> - 			[self sign = -1
>  				ifTrue: [aStream print: '-'].
>  			self = 0.0
>  				ifTrue: [aStream print: '0.0'. ^ self]
>  				ifFalse: [aStream writeNumber:self negated base: base]]!
> 
> Item was removed:
> - ----- 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!
> 
> Item was changed:
>  ----- Method: Float>>printOn:base: (in category 'printing') -----
>  printOn: aStream base: base
>  	"Print the receiver with the minimal number of digits that describes it unambiguously.
>  	This way, every two different Float will have a different printed representation.
>  	More over, every Float can be reconstructed from its printed representation with #readFrom:." 
> 
>  	self isNaN ifTrue: [aStream nextPutAll: 'NaN'. ^ self]. "check for NaN before sign"
>  	self > 0.0
>  		ifTrue: [self absPrintExactlyOn: aStream base: base]
>  		ifFalse:
> + 			[self signBit = 1
> - 			[self sign = -1
>  				ifTrue: [aStream nextPutAll: '-'].
>  			self = 0.0
>  				ifTrue: [aStream nextPutAll: '0.0']
>  				ifFalse: [self negated absPrintExactlyOn: aStream base: base]]!
> 
> Item was changed:
>  ----- Method: Float>>printOn:maxDecimalPlaces: (in category 'printing') -----
>  printOn: aStream maxDecimalPlaces: placesDesired
>  	"Refine super implementation in order to avoid any rounding error caused by rounded or roundTo:"
>  	
>  	self isFinite ifFalse: [^self printOn: aStream].
>  	self > 0.0
>  		ifTrue: [self absPrintExactlyOn: aStream base: 10 decimalPlaces: placesDesired showTrailingFractionalZeros: false]
>  		ifFalse:
> + 			[self signBit = 1
> - 			[self sign = -1
>  				ifTrue: [aStream nextPutAll: '-'].
>  			self = 0.0
>  				ifTrue: [aStream nextPutAll: '0.0']
>  				ifFalse: [self absPrintExactlyOn: aStream base: 10 decimalPlaces: placesDesired showTrailingFractionalZeros: false]]!
> 
> Item was changed:
>  ----- Method: Float>>printOn:showingDecimalPlaces: (in category 'printing') -----
>  printOn: aStream showingDecimalPlaces: placesDesired
>  	"Refine super implementation in order to avoid any rounding error caused by rounded or roundTo:"
>  	
>  	self isFinite ifFalse: [^self printOn: aStream].
>  	self > 0.0
>  		ifTrue: [self absPrintExactlyOn: aStream base: 10 decimalPlaces: placesDesired showTrailingFractionalZeros: true]
>  		ifFalse:
> + 			[self signBit = 1
> - 			[self sign = -1
>  				ifTrue: [aStream nextPutAll: '-'].
>  			self = 0.0
>  				ifTrue:
>  					[aStream nextPut: $0.
>  					placesDesired > 0 ifTrue: [aStream nextPut: $.; next: placesDesired put: $0]]
>  				ifFalse: [self absPrintExactlyOn: aStream base: 10 decimalPlaces: placesDesired showTrailingFractionalZeros: true]]!
> 
> Item was removed:
> - ----- Method: Float>>sign (in category 'mathematical functions') -----
> - sign
> - 	"Answer 1 if the receiver is greater than 0, -1 if less than 0, else 0.
> - 	Handle IEEE-754 negative-zero by reporting a sign of -1"
> - 
> - 	self > 0.0 ifTrue: [ ^1 ].
> - 	self < 0.0 ifTrue: [ ^-1 ].
> - 	^0 - ((self at: 1) bitShift: -31) "-1 for negative zero, 0 otherwise"!
> 
> Item was removed:
> - ----- Method: Float>>sign: (in category 'mathematical functions') -----
> - sign: aNumber
> - 	"Return a Number with the same sign as aNumber and same magnitude as self.
> - 	Implementation is different from super to handle the special case of Float negativeZero."
> - 
> - 	(self = 0.0 and: [aNumber sign negative]) ifTrue: [^Float negativeZero].
> - 	^aNumber copySignTo: self!
> 
> Item was added:
> + ----- Method: Float>>signBit (in category 'mathematical functions') -----
> + signBit
> + 	"Answer 1 if the receiver has sign bit set (including case of IEEE-754 negative-zero).
> + 	Answer 0 otherwise"
> + 
> + 	^((self at: 1) bitShift: -31)!
> 
> Item was changed:
>  ----- Method: Float>>storeOn:base: (in category 'printing') -----
>  storeOn: aStream base: base 
>  	"Print the Number exactly so it can be interpreted back unchanged"
>  	self isFinite
> + 		ifTrue: [self signBit = 1 ifTrue: [aStream nextPutAll: '-'].
> - 		ifTrue: [self sign = -1 ifTrue: [aStream nextPutAll: '-'].
>  			base = 10 ifFalse: [aStream print: base; nextPut: $r].
>  			self = 0.0
>  				ifTrue: [aStream nextPutAll: '0.0']
>  				ifFalse: [self abs absPrintExactlyOn: aStream base: base]]
>  		ifFalse: [self isNaN
>  				ifTrue: [aStream nextPutAll: 'Float nan']
>  				ifFalse: [self > 0.0
>  						ifTrue: [aStream nextPutAll: 'Float infinity']
>  						ifFalse: [aStream nextPutAll: 'Float infinity negated']]]!
> 
> Item was removed:
> - ----- 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 added:
> + ----- Method: LargeNegativeInteger>>signBit (in category 'testing') -----
> + signBit
> + 	"Optimization."
> + 
> + 	^1
> + !
> 
> Item was added:
> + ----- Method: LargePositiveInteger>>signBit (in category 'testing') -----
> + signBit
> + 	"Optimization."
> + 
> + 	^0!
> 
> 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 signBit = 0
> - 	^ self positive
>  		ifTrue: [aNumber abs]
> + 		ifFalse: [aNumber abs negated].!
> - 		ifFalse: [aNumber withNegativeSign].!
> 
> Item was added:
> + ----- Method: Number>>signBit (in category 'mathematical functions') -----
> + signBit
> + 	"Answer 1 if the receiver is negative, zero otherwise."
> + 
> + 	self < 0 ifTrue: [^1].
> + 	^0!
> 
> Item was removed:
> - ----- Method: Number>>withNegativeSign (in category 'converting') -----
> - withNegativeSign
> - 	"Answer a number with same magnitude than receiver and negative sign."
> - 	^self abs negated!
> 
> 


On 27.01.2017, at 19:56, Martin McClure via Glass <glass at lists.gemtalksystems.com> wrote:

> On 01/27/2017 10:51 AM, monty via Glass wrote:
>> Thanks Dale and Martin for your help.
> 
> You're welcome!
> 
> -Martin
> 
> _______________________________________________
> Glass mailing list
> Glass at lists.gemtalksystems.com
> http://lists.gemtalksystems.com/mailman/listinfo/glass



More information about the Glass mailing list