The Trunk: Kernel-nice.683.mcz

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

The Trunk: Kernel-nice.683.mcz

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

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

Name: Kernel-nice.683
Author: nice
Time: 26 April 2012, 7:06:10.666 pm
UUID: a7c12ee7-fee9-ae44-b849-f314f0859c25
Ancestors: Kernel-eem.682, Kernel-nice.652

Merge with nice.652 (Float unambiguous printing).

=============== Diff against Kernel-eem.682 ===============

Item was changed:
  ----- Method: Float>>absPrintExactlyOn:base: (in category 'printing') -----
  absPrintExactlyOn: aStream base: base
  "Print my value on a stream in the given base.  Assumes that my value is strictly
  positive; negative numbers, zero, and NaNs have already been handled elsewhere.
  Based upon the algorithm outlined in:
  Robert G. Burger and R. Kent Dybvig
  Printing Floating Point Numbers Quickly and Accurately
  ACM SIGPLAN 1996 Conference on Programming Language Design and Implementation
  June 1996.
  This version guarantees that the printed representation exactly represents my value
  by using exact integer arithmetic."
 
  | significand exp baseExpEstimate r s mPlus mMinus scale roundingIncludesLimits d tc1 tc2 fixedFormat decPointCount slowbit shead |
  self isInfinite ifTrue: [aStream nextPutAll: 'Infinity'. ^ self].
  significand := self significandAsInteger.
  roundingIncludesLimits := significand even.
  exp := (self exponent - 52) max: MinValLogBase2.
  baseExpEstimate := (self exponent * base asFloat reciprocalLogBase2 - 1.0e-10) ceiling.
  exp >= 0
  ifTrue:
  [significand ~= 16r10000000000000
  ifTrue:
  [r := significand bitShift: 1 + exp.
  s := 2.
  mPlus := mMinus := 1 bitShift: exp]
  ifFalse:
  [r := significand bitShift: 2 + exp.
  s := 4.
  mPlus := 2 * (mMinus := 1 bitShift: exp)]]
  ifFalse:
  [(exp = MinValLogBase2 or: [significand ~= 16r10000000000000])
  ifTrue:
  [r := significand bitShift: 1.
  s := 1 bitShift: 1 - exp.
  mPlus := mMinus := 1]
  ifFalse:
  [r := significand bitShift: 2.
  s := 1 bitShift: 2 - exp.
  mPlus := 2.
  mMinus := 1]].
  baseExpEstimate >= 0
  ifTrue: [s := s * (base raisedToInteger: baseExpEstimate)]
  ifFalse:
  [scale := base raisedToInteger: baseExpEstimate negated.
  r := r * scale.
  mPlus := mPlus * scale.
  mMinus := mMinus * scale].
+ ((r + mPlus >= s) and: [roundingIncludesLimits or: [r + mPlus > s]])
- ((r + mPlus < s) not and: [roundingIncludesLimits or: [r + mPlus > s]])
  ifTrue: [baseExpEstimate := baseExpEstimate + 1]
  ifFalse:
  [r := r * base.
  mPlus := mPlus * base.
  mMinus := mMinus * base].
  (fixedFormat := baseExpEstimate between: -3 and: 6)
  ifTrue:
  [decPointCount := baseExpEstimate.
  baseExpEstimate <= 0
  ifTrue: [aStream nextPutAll: ('0.000000' truncateTo: 2 - baseExpEstimate)]]
  ifFalse:
  [decPointCount := 1].
  slowbit := 1 - s lowBit .
  shead := s bitShift: slowbit.
  [d := (r bitShift: slowbit) // shead.
  r := r - (d * s).
+ (tc1 := (r <= mMinus) and: [roundingIncludesLimits or: [r < mMinus]]) |
+ (tc2 := (r + mPlus >= s) and: [roundingIncludesLimits or: [r + mPlus > s]])] whileFalse:
- (tc1 := (r > mMinus) not and: [roundingIncludesLimits or: [r < mMinus]]) |
- (tc2 := (r + mPlus < s) not and: [roundingIncludesLimits or: [r + mPlus > s]])] whileFalse:
  [aStream nextPut: (Character digitValue: d).
  r := r * base.
  mPlus := mPlus * base.
  mMinus := mMinus * base.
+ (decPointCount := decPointCount - 1) = 0 ifTrue: [aStream nextPut: $.]].
- decPointCount := decPointCount - 1.
- decPointCount = 0 ifTrue: [aStream nextPut: $.]].
  tc2 ifTrue:
  [(tc1 not or: [r * 2 >= s]) ifTrue: [d := d + 1]].
  aStream nextPut: (Character digitValue: d).
  decPointCount > 0
  ifTrue:
+ [decPointCount - 1 to: 1 by: -1 do: [:i | aStream nextPut: $0].
+ aStream nextPutAll: '.0'].
+ fixedFormat
+ ifFalse:
+ [aStream nextPut: $e.
+ aStream nextPutAll: (baseExpEstimate - 1) printString]!
- [decPointCount - 1 to: 1 by: -1 do: [:i | aStream nextPut: $0].
- aStream nextPutAll: '.0'].
- fixedFormat ifFalse:
- [aStream nextPut: $e.
- aStream nextPutAll: (baseExpEstimate - 1) printString]!

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:."
- "Handle sign, zero, and NaNs; all other values passed to absPrintOn:base:"
 
  self isNaN ifTrue: [aStream nextPutAll: 'NaN'. ^ self]. "check for NaN before sign"
  self > 0.0
+ ifTrue: [self absPrintExactlyOn: aStream base: base]
- ifTrue: [self absPrintOn: aStream base: base]
  ifFalse:
  [self sign = -1
  ifTrue: [aStream nextPutAll: '-'].
  self = 0.0
+ ifTrue: [aStream nextPutAll: '0.0']
+ ifFalse: [self negated absPrintExactlyOn: aStream base: base]]!
- ifTrue: [aStream nextPutAll: '0.0'. ^ self]
- ifFalse: [self negated absPrintOn: aStream base: base]]!