'From Squeak4.2 of 26 February 2011 [latest update: #11044] on 27 February 2011 at 9:55:52 pm'! "Change Set: Float-printPaddedWith-dtl Date: 27 February 2011 Author: David T. Lewis A test and a fix for the bug reported in http://lists.gforge.inria.fr/pipermail/pharo-users/2011-February/001569.html"! !Float methodsFor: 'printing' stamp: 'dtl 2/27/2011 21:39'! printPaddedWith: aCharacter to: aNumber "Answer the string containing the ASCII representation of the receiver padded on the left with aCharacter to be at least on aNumber integerPart characters and padded the right with aCharacter to be at least anInteger fractionPart characters." | aStream digits fPadding fLen iPadding iLen curLen periodIndex | #Numeric. "2000/03/04 Harmon R. Added Date and Time support" aStream := WriteStream on: (String new: 10). self printOn: aStream. digits := aStream contents. periodIndex := digits indexOf: $.. curLen := periodIndex - 1. iLen := aNumber integerPart. curLen < iLen ifTrue: [iPadding := (String new: (iLen - curLen) asInteger) atAllPut: aCharacter; yourself] ifFalse: [iPadding := '']. curLen := digits size - periodIndex. "n.b. Treat aNumber as a string format specifier rather than as a number, because floating point truncation can produce incorrect results for the fraction part." fLen := (aNumber asString copyAfterLast: $. ) ifNotEmpty: [:s | s asInteger] ifEmpty: [ 0 ]. curLen < fLen ifTrue: [fPadding := (String new: fLen - curLen) atAllPut: aCharacter; yourself] ifFalse: [fPadding := '']. ^ iPadding , digits , fPadding! ! !FloatTest methodsFor: 'printing' stamp: 'dtl 2/27/2011 21:01'! testPrintPaddedWithTo "This bug was reported in http://lists.gforge.inria.fr/pipermail/pharo-users/2011-February/001569.html. The problem was caused by treating the format specifier as a number rather than as a string, such the the number may be a Float subject to floating point rounding errors. The solution to treat the format specifier as a string, and extract the integer fields before and after the decimal point in the string." self assert: [(1.0 printPaddedWith: $0 to: 2.2) = '01.00']. self assert: [(1.0 printPaddedWith: $X to: 2.2) = 'X1.0X']. self assert: [(1.0 printPaddedWith: $0 to: 2) = '01.0']. self assert: [(12345.6789 printPaddedWith: $0 to: 2) = '12345.6789']. self assert: [(12345.6789 printPaddedWith: $0 to: 2.2) = '12345.6789']. self assert: [(12.34 printPaddedWith: $0 to: 2.2) = '12.34']. self assert: [(12345.6789 printPaddedWith: $0 to: 2.2) = '12345.6789']. self assert: [(123.456 printPaddedWith: $X to: 4.4) = 'X123.456X']. self assert: [(1.0 printPaddedWith: $0 to: 2.1) = '01.0']. self assert: [(1.0 printPaddedWith: $0 to: 2.2) = '01.00']. self assert: [(1.0 printPaddedWith: $0 to: 2.3) = '01.000']. "previously failed due to float usage" self assert: [(1.0 printPaddedWith: $0 to: 2.4) = '01.0000']. "previously failed due to float usage" self assert: [(1.0 printPaddedWith: $0 to: 2.5) = '01.00000'] ! !