Number names?
Jarvis, Robert P. (Contingent)
Jarvisb at timken.com
Fri Aug 24 19:49:19 UTC 2001
> From: Dan Ingalls [mailto:Dan at SqueakLand.org]
>
> Does anyone have or know of, in Squeak or any other Smalltalk...
>
> a method that if you give it
>
> SmallInteger maxVal
>
> it will respond with...
>
> 'one billion, seventy-three million, seven hundred
> forty-one thousand, eight hundred twenty-three'
Sorry this isn't in change notice format but I did it up in Dolphin
Smalltalk. Try adding the following methods (four in Number, one in
Fraction):
Number>>asSpoken
"Answers a String containing the text for this number in American
English."
| text subStrings groups leftOfDecimal rightOfDecimal exponent
groupText
groupCount groupSize result |
groupText := #('' 'thousand' 'million' 'billion' 'trillion'
'quadrillion' 'quintillion' 'sextillion' 'septillion' 'octillion').
self > 999999999999999999999999999999 ifTrue: [ ^'a really big
number' ].
leftOfDecimal := ''.
rightOfDecimal := ''.
exponent := ''.
result := String new.
text := self printString.
text last isDigit ifFalse: [ text := text leftString: text size - 1
].
(text at: 1) = $+ ifTrue: [ result := 'positive '. text := text
rightString: text size - 1 ].
(text at: 1) = $- ifTrue: [ result := 'negative '. text := text
rightString: text size - 1 ].
subStrings := text subStrings: '.'.
leftOfDecimal := subStrings at: 1.
subStrings size > 1 ifTrue: [
subStrings := (subStrings at: 2) subStrings: 'e'.
rightOfDecimal := subStrings at: 1.
subStrings size > 1
ifTrue: [ exponent := subStrings at: 2 ] ].
groupCount := leftOfDecimal size // 3.
leftOfDecimal size \\ 3 ~= 0 ifTrue: [ groupCount := groupCount + 1
].
groups := Array new: groupCount.
1 to: groupCount do: [ :i |
i = 1
ifTrue: [
leftOfDecimal size \\ 3 = 0
ifTrue: [ groupSize := 3 ]
ifFalse: [ groupSize :=
leftOfDecimal size \\ 3 ] ]
ifFalse: [ groupSize := 3 ].
groups at: i put: (leftOfDecimal leftString: groupSize).
leftOfDecimal := leftOfDecimal rightString: leftOfDecimal
size - groupSize ].
groups := groups reverse.
groups size = 1
ifTrue:
[ text := (groups at: 1).
text size = 3 ifTrue: [
(text at: 1) ~= $0 ifTrue: [
result := result, (self spokenDigit:
(text at: 1)), ' hundred ' ].
text := text rightString: 2 ].
text size = 2 ifTrue: [
(text at: 1) ~= $0
ifTrue: [
(text at: 1) ~= $1
ifTrue: [ result :=
result, (self spokenTensDigit: (text at: 1)), ' '.
text :=
text rightString: 1 ]
ifFalse: [ result :=
result, (self spokenTeensDigit: (text at: 2)).
text :=
'' ] ]
ifFalse: [
(text at: 2) ~= $0 ifTrue: [
result := result, 'and ' ].
text := text rightString: 1
] ].
text size = 1 ifTrue: [
(text at: 1) ~= $0 ifTrue: [
result := result, (self spokenDigit:
(text at: 1)) ] ] ]
ifFalse: [
groups size to: 1 by: -1 do: [ :i |
result := result, (groups at: i) asNumber
asSpoken, ' ', (groupText at: i), ' ' ] ].
rightOfDecimal size > 0 ifTrue: [
result := result, ' point '.
1 to: rightOfDecimal size do: [ :i |
result := result, (rightOfDecimal at: i) asString
asNumber asSpoken, ' ' ] ].
exponent size > 0 ifTrue: [
result := result, 'times ten to the ', (exponent
rightString: exponent size - 1) asString asNumber asSpoken, 'th' ].
^result
Number>>spokenDigit: aCharacter
| digitText |
digitText := #('zero' 'one' 'two' 'three' 'four' 'five' 'six'
'seven' 'eight' 'nine').
^digitText at: aCharacter asString asNumber + 1
Number>>spokenTeensDigit: aCharacter
| digitText |
digitText := #('ten' 'eleven' 'twelve' 'thirteen' 'fourteen'
'fifteen' 'sixteen' 'seventeen' 'eighteen' 'nineteen').
^digitText at: aCharacter asString asNumber + 1
Number>>spokenTensDigit: aCharacter
| digitText |
digitText := #('' '' 'twenty' 'thirty' 'forty' 'fifty' 'sixty'
'seventy' 'eighty' 'ninety').
^digitText at: aCharacter asString asNumber + 1
Fraction>>asSpoken
^self numerator asSpoken, ' over ', self denominator asSpoken
This hasn't been extensively tested but seems to work OK for Integers,
Fractions, and some Floats. Anything with an exponent comes out a bit
hokey, but at least it's something to play with.
Bob Jarvis
Compuware @ Timken
More information about the Squeak-dev
mailing list
|