[squeak-dev] The Trunk: Kernel-nice.602.mcz

commits at source.squeak.org commits at source.squeak.org
Mon Jun 27 18:27:52 UTC 2011


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

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

Name: Kernel-nice.602
Author: nice
Time: 27 June 2011, 8:27:00.479 pm
UUID: 5466a1ae-e947-4881-b71f-e83278dc1e33
Ancestors: Kernel-bf.601

Minor tweaks:
Use a better approximation for counting digits in base 10
Use raisedToInteger: since we now the argument 'base' is Integer
Change arTanh error message because (between -1 and 1) is more inline with Smalltalk message #between:and: than (between 1 and -1).
Simplify ulp since #abs matches #ulp return value for any non finite number.

=============== Diff against Kernel-bf.601 ===============

Item was changed:
  ----- Method: Float>>arTanh (in category 'mathematical functions') -----
  arTanh
  	"Answer receiver's area hyperbolic tangent.
  	That is the inverse function of tanh."
  
  	self = 0.0 ifTrue: [^self].	"Handle negativeZero"
  	self abs = 1 ifTrue: [^self copySignTo: Float infinity].
  	self abs > 1 
  		ifTrue: 
+ 			[^DomainError signal: 'Receiver must be between -1.0 and 1.0'].
- 			[^DomainError signal: 'Receiver must be between 1.0 and -1.0'].
  	^((1 + self) / (1 - self)) ln / 2!

Item was changed:
  ----- Method: Float>>ulp (in category 'truncation and round off') -----
  ulp
  	"Answer the unit of least precision of self (the power of two corresponding to last bit of mantissa)"
  	
  	| exponent |
+ 	self isFinite ifFalse: [^self abs].
- 	self isFinite ifFalse: [
- 		self isNaN ifTrue: [^self].
- 		^Float infinity].
  	self = 0.0 ifTrue: [^Float fmin].
  	exponent := self exponent.
  	^exponent < self class emin
  		ifTrue: [Float fminDenormalized]
   		ifFalse: [Float epsilon timesTwoPower: exponent]!

Item was changed:
  ----- Method: Integer>>numberOfDigitsInBase: (in category 'printing') -----
  numberOfDigitsInBase: b 
  	"Return how many digits are necessary to print this number in base b.
  	This does not count any place for minus sign, radix prefix or whatever.
  	Note that this algorithm may cost a few operations on LargeInteger."
  
  	| nDigits q total |
  	self negative ifTrue: [^self negated numberOfDigitsInBase: b].
  	self < b ifTrue: [^1].
  	b isPowerOfTwo ifTrue: [^self highBit + b highBit - 2 quo: b highBit - 1].
  	
  	"A conversion from base 2 to base b has to be performed.
  	This algorithm avoids Float computations like (self log: b) floor + 1,
  	1) because they are inexact
  	2) because LargeInteger might overflow
  	3) because this algorithm might be cheaper than conversion"
  
  	q := self.
  	total := 0.
  	["Make an initial nDigits guess that is lower than or equal to required number of digits"
  	nDigits := b = 10
  		ifTrue: [((q highBit - 1) * 1233 >> 12) + 1. "This is because (2 log)/(10 log)*4096 is slightly greater than 1233"]
  		ifFalse: [q highBit quo: b highBit].
  	total := total + nDigits.
  	
  	"See how many digits remains above these first nDigits guess"
+ 	(q := q quo: (b raisedToInteger: nDigits)) < b] whileFalse.
- 	(q := q quo: (b raisedTo: nDigits)) < b] whileFalse.
  	^q = 0
  		ifTrue: [total]
  		ifFalse: [total + 1]!

Item was changed:
  ----- Method: LargePositiveInteger>>printOn:base: (in category 'printing') -----
  printOn: aStream base: b
  	"Append a representation of this number in base b on aStream.
  	In order to reduce cost of LargePositiveInteger ops, split the number in approximately two equal parts in number of digits."
  	
  	| halfDigits halfPower head tail nDigitsUnderestimate |
  	"Don't engage any arithmetic if not normalized"
  	(self digitLength = 0 or: [(self digitAt: self digitLength) = 0]) ifTrue: [^self normalize printOn: aStream base: b].
  	
  	nDigitsUnderestimate := b = 10
+ 		ifTrue: [((self highBit - 1) * 1233 >> 12) + 1. "This is because (2 log)/(10 log)*4096 is slightly greater than 1233"]
- 		ifTrue: [((self highBit - 1) * 3 quo: 10) + 1 "because 1024 is almost a kilo"]
  		ifFalse: [self highBit quo: b highBit].
  		
  	"splitting digits with a whole power of two is more efficient"
  	halfDigits := 1 bitShift: nDigitsUnderestimate highBit - 2.
  	
  	halfDigits <= 1
  		ifTrue: ["Hmmm, this could happen only in case of a huge base b... Let lower level fail"
  			^self printOn: aStream base: b nDigits: (self numberOfDigitsInBase: b)].
  	
  	"Separate in two halves, head and tail"
  	halfPower := b raisedToInteger: halfDigits.
  	head := self quo: halfPower.
  	tail := self - (head * halfPower).
  	
  	"print head"
  	head printOn: aStream base: b.
  	
  	"print tail without the overhead to count the digits"
  	tail printOn: aStream base: b nDigits: halfDigits!




More information about the Squeak-dev mailing list