--- a/PrintfScanf.st Thu Jun 15 09:58:16 2017 +0200
+++ b/PrintfScanf.st Sat Jun 17 03:09:27 2017 +0200
@@ -1,5 +1,3 @@
-"{ Encoding: utf8 }"
-
"{ Package: 'stx:libbasic2' }"
"{ NameSpace: Smalltalk }"
@@ -52,6 +50,12 @@
self new printf:'%- 10.4s%.2e' arguments: { 'abcdefghijkl' . Float pi }
self new printf:'%8.3f' arguments: { 200 sqrt negated }
+ self printf:'%8.3f' on:Transcript arguments: { 200 sqrt negated }
+ self printf:'%10.4f' on:Transcript arguments: { 200 sqrt negated }
+ self printf:'%20.10f' on:Transcript arguments: { 200 sqrt negated }
+
+ self printf:'%20.10f' on:Transcript arguments: { 1.234567890123456789f }
+ self printf:'%20.10f' on:Transcript arguments: { 1.234567890123456789q }
self new printf:'%x' arguments: #(16r41)
self new printf:'%#x' arguments: #(16r41)
@@ -97,11 +101,102 @@
!PrintfScanf class methodsFor:'printing'!
+printf:formatString argument:arg
+ "Format and print the receiver with <arg> formatted in C style,
+ as described in the UTek manual page for printf(3)."
+
+ ^ self printf:formatString arguments:{ arg }
+
+ "
+ self printf:'%e' on:Transcript argument:(1.234 asShortFloat)
+ self printf:'%e' on:Transcript argument:(1.234 asFloat)
+ self printf:'%e' on:Transcript argument:(1.234 asLongFloat)
+ self printf:'%e' on:Transcript argument:(1.234 asQDouble)
+ self printf:'%e' on:Transcript argument:(1.234 asInteger)
+
+ self printf:'%10e' on:Transcript argument:(1.234 asShortFloat)
+ self printf:'%10e' on:Transcript argument:(1.234 asFloat)
+ self printf:'%10e' on:Transcript argument:(1.234 asLongFloat)
+ self printf:'%10e' on:Transcript argument:(1.234 asQDouble)
+ self printf:'%10e' on:Transcript argument:(1.234 asInteger)
+
+ self printf:'%010e' on:Transcript argument:(1.234 asInteger)
+ self printf:'%-10e' on:Transcript argument:(1.234 asInteger)
+
+ self printf:'%10.9f' on:Transcript argument:(1.2345 asShortFloat)
+ self printf:'%10.9f' on:Transcript argument:(1.2345 asFloat)
+ self printf:'%10.9f' on:Transcript argument:(1.2345 asLongFloat)
+ self printf:'%10.9f' on:Transcript argument:(1.2345 asQDouble)
+ self printf:'%10.9f' on:Transcript argument:(1.2345 asInteger)
+ "
+
+ "Created: / 16-06-2017 / 14:50:08 / cg"
+!
+
printf:formatString arguments:args
"Format and print the receiver with <args> formatted in C style,
as described in the UTek manual page for printf(3)."
^ self new printf:formatString arguments:args
+
+ "
+ self printf:'%e' on:Transcript arguments:{ (1.234 asShortFloat) }
+ self printf:'%e' on:Transcript arguments:{ (1.234 asFloat) }
+ self printf:'%e' on:Transcript arguments:{ (1.234 asLongFloat) }
+ self printf:'%e' on:Transcript arguments:{ (1.234 asQDouble) }
+ self printf:'%e' on:Transcript arguments:{ (1.234 asInteger) }
+
+ self printf:'%10e' on:Transcript arguments:{ (1.234 asShortFloat) }
+ self printf:'%10e' on:Transcript arguments:{ (1.234 asFloat) }
+ self printf:'%10e' on:Transcript arguments:{ (1.234 asLongFloat) }
+ self printf:'%10e' on:Transcript arguments:{ (1.234 asQDouble) }
+ self printf:'%10e' on:Transcript arguments:{ (1.234 asInteger) }
+
+ self printf:'%010e' on:Transcript arguments:{ (1.234 asInteger) }
+ self printf:'%-10e' on:Transcript arguments:{ (1.234 asInteger) }
+
+ self printf:'%10.9f' on:Transcript arguments:{ (1.2345 asShortFloat) }
+ self printf:'%10.9f' on:Transcript arguments:{ (1.2345 asFloat) }
+ self printf:'%10.9f' on:Transcript arguments:{ (1.2345 asLongFloat) }
+ self printf:'%10.9f' on:Transcript arguments:{ (1.2345 asQDouble) }
+ self printf:'%10.9f' on:Transcript arguments:{ (1.2345 asInteger) }
+ "
+
+ "Modified (comment): / 16-06-2017 / 10:37:44 / cg"
+!
+
+printf:formatString on:outStream argument: arg
+ "Format and print formatString on <outStream> with <arg>
+ formatted in C style, as described in the UTek manual page for
+ printf(3). This method is designed for producing output
+ suitable for a machine."
+
+ ^ self printf:formatString on:outStream arguments:{ arg }
+
+ "
+ self printf:'%e' on:Transcript argument:(1.234 asShortFloat). Transcript cr.
+ self printf:'%e' on:Transcript argument:(1.234 asFloat) . Transcript cr.
+ self printf:'%e' on:Transcript argument:(1.234 asLongFloat) . Transcript cr.
+ self printf:'%e' on:Transcript argument:(1.234 asQDouble) . Transcript cr.
+ self printf:'%e' on:Transcript argument:(1.234 asInteger) . Transcript cr.
+
+ self printf:'%10e' on:Transcript argument:(1.234 asShortFloat). Transcript cr.
+ self printf:'%10e' on:Transcript argument:(1.234 asFloat) . Transcript cr.
+ self printf:'%10e' on:Transcript argument:(1.234 asLongFloat) . Transcript cr.
+ self printf:'%10e' on:Transcript argument:(1.234 asQDouble) . Transcript cr.
+ self printf:'%10e' on:Transcript argument:(1.234 asInteger) . Transcript cr.
+
+ self printf:'%010e' on:Transcript argument:(1.234 asInteger) . Transcript cr.
+ self printf:'%-10e' on:Transcript argument:(1.234 asInteger) . Transcript cr.
+
+ self printf:'%10.9f' on:Transcript argument:(1.2345 asShortFloat). Transcript cr.
+ self printf:'%10.9f' on:Transcript argument:(1.2345 asFloat) . Transcript cr.
+ self printf:'%10.9f' on:Transcript argument:(1.2345 asLongFloat) . Transcript cr.
+ self printf:'%10.9f' on:Transcript argument:(1.2345 asQDouble) . Transcript cr.
+ self printf:'%10.9f' on:Transcript argument:(1.2345 asInteger) . Transcript cr.
+ "
+
+ "Created: / 16-06-2017 / 14:50:40 / cg"
!
printf:formatString on:outStream arguments: args
@@ -111,6 +206,31 @@
suitable for a machine."
^ self new printf:formatString on:outStream arguments: args
+
+ "
+ self printf:'%e' on:Transcript arguments:{ (1.234 asShortFloat) }
+ self printf:'%e' on:Transcript arguments:{ (1.234 asFloat) }
+ self printf:'%e' on:Transcript arguments:{ (1.234 asLongFloat) }
+ self printf:'%e' on:Transcript arguments:{ (1.234 asQDouble) }
+ self printf:'%e' on:Transcript arguments:{ (1.234 asInteger) }
+
+ self printf:'%10e' on:Transcript arguments:{ (1.234 asShortFloat) }
+ self printf:'%10e' on:Transcript arguments:{ (1.234 asFloat) }
+ self printf:'%10e' on:Transcript arguments:{ (1.234 asLongFloat) }
+ self printf:'%10e' on:Transcript arguments:{ (1.234 asQDouble) }
+ self printf:'%10e' on:Transcript arguments:{ (1.234 asInteger) }
+
+ self printf:'%010e' on:Transcript arguments:{ (1.234 asInteger) }
+ self printf:'%-10e' on:Transcript arguments:{ (1.234 asInteger) }
+
+ self printf:'%10.9f' on:Transcript arguments:{ (1.2345 asShortFloat) }
+ self printf:'%10.9f' on:Transcript arguments:{ (1.2345 asFloat) }
+ self printf:'%10.9f' on:Transcript arguments:{ (1.2345 asLongFloat) }
+ self printf:'%10.9f' on:Transcript arguments:{ (1.2345 asQDouble) }
+ self printf:'%10.9f' on:Transcript arguments:{ (1.2345 asInteger) }
+ "
+
+ "Modified (comment): / 16-06-2017 / 14:51:08 / cg"
! !
!PrintfScanf class methodsFor:'scanning'!
@@ -136,17 +256,25 @@
!PrintfScanf methodsFor:'helpers'!
absDecimalPrintFloat:aFloat on:aStream digits:digits
- "Place a string representation of the receiver on <aStream> using <digits> significant digits, using decimal notation."
+ "Place a string representation of the receiver on <aStream>,
+ using <digits> significant digits, using decimal notation."
- |exp x fuzz i|
+"
+ self printf:'%20.10f' on:Transcript arguments: { 1.234567890123456789f }
+ self printf:'%20.10f' on:Transcript arguments: { 1.234567890123456789q }
+"
+
+ |absVal exp x fuzz i|
+
+ absVal := aFloat abs.
"x is myself normalized to (1.0, 10.0), exp is my exponent"
- exp := aFloat abs < 1.0 ifTrue:[
- (10.0 / aFloat abs) log floor negated
- ] ifFalse:[
- aFloat abs log floor
- ].
- x := aFloat abs / (10.0 raisedTo:exp).
+ exp := absVal < 1.0
+ ifTrue:[
+ (10.0 / absVal) log floor negated ]
+ ifFalse:[
+ absVal log floor].
+ x := absVal / (10.0 raisedTo:exp).
fuzz := 10.0 raisedTo:1 - digits.
x := 0.5 * fuzz + x.
x >= 10.0 ifTrue:[
@@ -154,10 +282,14 @@
x := x / 10.0.
exp := exp + 1
].
+
exp < 0 ifTrue:[
- 1 to:1 - exp do:[:j |
- aStream nextPut:('0.000000000000' at:j)
- ]
+ 1 to:(1 - exp) do:[:j |
+ "/ cg: huh - what sort of code is that????
+ "/ aStream nextPut:('0.000000000000' at:j)
+ aStream nextPut:(j == 2 ifTrue:[$.] ifFalse:[$0])
+ ].
+
].
[ x >= fuzz ] whileTrue:[
"use fuzz to track significance"
@@ -177,10 +309,13 @@
aStream nextPut:$.
]
]
+
+ "Modified (comment): / 16-06-2017 / 10:40:28 / cg"
!
absPrintFloat:aFloat on:aStream digits:digits
- "Place a string representation of the receiver on <aStream> using <digits> significant digits."
+ "Place a string representation of the receiver on <aStream>,
+ using <digits> significant digits."
(aFloat < 1.0e6 and:[ aFloat > 1.0e-4 ]) ifTrue:[
self
@@ -193,20 +328,25 @@
on:aStream
digits:digits
]
+
+ "Modified (comment): / 16-06-2017 / 10:25:33 / cg"
!
absScientificPrintFloat:aFloat on:aStream digits:digits
- "Place a string representation of the receiver on <aStream> using <digits> significant digits, using scientific notation."
+ "Place a string representation of the receiver on <aStream>,
+ using <digits> significant digits, using scientific notation."
- |exp fuzz x q i|
+ |absVal exp fuzz x q i|
+ absVal := aFloat abs.
+
"x is myself normalized to [1.0, 10.0), exp is my exponent"
- exp := aFloat abs < 1.0 ifTrue:[
- (10.0 / aFloat abs) log floor negated
- ] ifFalse:[
- aFloat abs log floor
- ].
- x := aFloat abs / (10.0 raisedTo:exp).
+ exp := absVal < 1.0
+ ifTrue:[
+ (10.0 / absVal) log floor asInteger negated]
+ ifFalse:[
+ absVal log floor asInteger].
+ x := absVal / (10.0 raisedTo:exp).
fuzz := 10.0 raisedTo:1 - digits.
x := 0.5 * fuzz + x.
x >= 10.0 ifTrue:[ "check if rounding has unnormalized x"
@@ -235,6 +375,8 @@
].
aStream nextPut:$e.
q printOn:aStream
+
+ "Modified: / 16-06-2017 / 10:27:03 / cg"
!
formatArgCountFor:aFormatString
@@ -342,34 +484,39 @@
].
('feg' includes: char) ifTrue:[
- arg := argStream next asFloat.
- precision := precision min: 6.
- argString := WriteStream on:''.
- char == $g ifTrue:
- [self absPrintFloat:arg on: argString digits: precision + 1].
- char == $f ifTrue:
- [self absDecimalPrintFloat:arg on: argString digits: precision + arg abs log + 1].
- char == $e ifTrue:
- [self absScientificPrintFloat:arg on: argString digits: precision + 1].
- argString := argString contents.
- arg < 0
- ifTrue: [argString := '-', argString]
- ifFalse: [plus ifTrue: [argString := '+', argString]].
- (precision = 0 and: [pound not]) ifTrue:
- [(argString includes: $e)
- ifTrue: ["self halt"]
- ifFalse:
- [argString := arg truncated printString]].
- pound ifTrue:
- [(argString includes: $e)
- ifTrue: ["self halt"]
- ifFalse:
- [precision - (argString size - (argString indexOf: $.)) timesRepeat:
- [argString := argString, '0']]].
- ljust ifTrue: [outStream nextPutAll: argString].
- width - argString size timesRepeat: [outStream nextPut: pad].
- ljust ifFalse: [outStream nextPutAll: argString].
- ^inStream next
+ arg := argStream next asFloat.
+ arg isLimitedPrecisionReal ifTrue:[
+ precision := precision min: (arg defaultPrintPrecision).
+ ] ifFalse:[
+ precision := precision min:(Float defaultPrintPrecision).
+ ].
+ argString := WriteStream on:''.
+ char == $g ifTrue: [
+ self absPrintFloat:arg on: argString digits: precision + 1 ].
+ char == $f ifTrue: [
+ self absDecimalPrintFloat:arg on: argString digits: precision + arg abs log + 1].
+ char == $e ifTrue: [
+ self absScientificPrintFloat:arg on: argString digits: precision + 1].
+ argString := argString contents.
+ arg < 0
+ ifTrue: [argString := '-', argString]
+ ifFalse: [plus ifTrue: [argString := '+', argString]].
+ (precision = 0 and: [pound not]) ifTrue:[
+ (argString includes: $e)
+ ifTrue: ["self halt"]
+ ifFalse: [
+ argString := arg truncated printString]].
+ pound ifTrue:[
+ (argString includes: $e)
+ ifTrue: ["self halt"]
+ ifFalse:[
+ precision - (argString size - (argString indexOf: $.))
+ timesRepeat:[
+ argString := argString, '0']]].
+ ljust ifTrue: [outStream nextPutAll: argString].
+ width - argString size timesRepeat: [outStream nextPut: pad].
+ ljust ifFalse: [outStream nextPutAll: argString].
+ ^inStream next
].
char == $c ifTrue:[
@@ -392,7 +539,7 @@
char == $o ifTrue:[
arg := argStream next asInteger abs printStringRadix: 8.
- pound ifTrue: [arg := '0', arg]
+ pound ifTrue: [arg := '0', arg]
].
('xX' includes: char) ifTrue:[
@@ -406,8 +553,9 @@
char == $x ifTrue:[
1 to: arg size do: [:i |
- ('ABCDEF' includes: (arg at: i)) ifTrue:
- [arg at: i put: (arg at: i) asLowercase]
+ ('ABCDEF' includes: (arg at: i)) ifTrue:[
+ arg at: i put: (arg at: i) asLowercase
+ ]
]
].
@@ -417,32 +565,32 @@
ljust ifFalse: [outStream nextPutAll: (arg copyFrom: 1 to: precision)].
^ inStream next
- "Modified (format): / 24-07-2011 / 08:39:04 / cg"
+ "Modified: / 17-06-2017 / 03:00:07 / cg"
!
printf:aString arguments:args
"Format and print the receiver with <args> formatted in C style,
- as described in the UTek manual page for printf(3)."
+ as described in the UTek manual page for printf(3).
+ Returns the formatted printString."
|aStream|
aStream := WriteStream on:(aString species new:100).
- self
- printf:aString
- on:aStream
- arguments:args.
+ self printf:aString on:aStream arguments:args.
^ aStream contents
"
self new printf:'%d %x' arguments:#(1234 45054)
"
+
+ "Modified (comment): / 16-06-2017 / 15:09:01 / cg"
!
printf:aFormatString on:outStream arguments: args
"Format and print aFormatString on <outStream> with <args>
formatted in C style, as described in the UTek manual page for
- printf(3). This method is designed for producing output
- suitable for a machine."
+ printf(3).
+ This method is designed for producing output suitable for a machine."
| argStream inStream char |
@@ -455,6 +603,8 @@
self printArgFrom:inStream to:outStream arguments:argStream
]
]
+
+ "Modified (comment): / 16-06-2017 / 15:09:10 / cg"
! !
!PrintfScanf methodsFor:'scanning'!