Author: Raghunath Dhungel
How to convert numbers like 2345697.347 to "two billion, three hundred and
forty-five thousand, six hundred and ninety seven decimal three four seven."
Answer:
1 unit Inwordsu;
2
3 interface
4 uses SysUtils, Dialogs;
5
6 function InWords(const nNumber: Extended): string;
7
8 implementation
9
10 function InWords(const nNumber: Extended): string;
11 const
12 aUnits: array[0..9] of string = ('', 'one ', 'two ', 'three ', 'four ', 'five ',
13 'six ', 'seven ', 'eight ', 'nine ');
14 //Local function to convert decimal portion
15 function cDecimal(const cDecDitxt: string): string;
16 var
17 len, x, n: Integer;
18 nNumber: string[17];
19 begin
20 result := '';
21 nNumber := cDecDitxt;
22 //cut off Zeros to the right
23 while copy(nNumber, length(nNumber), 1) = '0' do
24 delete(nNumber, length(nNumber), 1);
25 len := length(nNumber);
26 //No need to convert if it is all zeros
27 if len = 0 then
28 exit;
29 //Start conversion !
30 for x := 1 to len do
31 begin
32 n := strToint(copy(nNumber, x, 1));
33 if n = 0 then
34 result := result + 'zero '
35 else
36 result := result + aUnits[n];
37 end;
38 if result <> '' then
39 result := ' decimal ' + trim(result);
40 end;
41
42 //Local function to convert the whole number portion
43 function Num2EngWords(const nNumber, nWordIndex: integer): string;
44 const
45 aLargeNumWords: array[0..5] of string = ('', 'thousand, ', 'million, ',
46 'billion, ', 'trillion, ', 'quadrillion, ');
47 aTens: array[0..8] of string = ('', 'twenty', 'thirty', 'forty', 'fifty',
48 'sixty',
49 'seventy', 'eighty', 'ninety');
50 aTwenties: array[10..19] of string = ('ten ', 'eleven ', 'twelve ', 'thirteen ',
51 'fourteen ', 'fifteen ', 'sixteen ', 'seventeen ', 'eighteen ', 'nineteen ');
52 var
53 nQtnt, nNum, nMod: Integer;
54 begin
55 result := '';
56 if nNumber < 1 then
57 exit;
58 nNum := nNumber;
59
60 if nNumber > 99 then
61 begin
62 //Pick up hundreds and leave others
63 nQtnt := nNum div 100;
64 nNum := nNum mod 100;
65 result := aUnits[nQtnt] + 'hundred and ';
66 end;
67 case nNum of
68 1..9: result := result + aUnits[nNum]; {one to nine}
69 10..19: result := result + aTwenties[nNum]; {ten to nineteen}
70 20..99:
71 begin
72 nQtnt := nNum div 10;
73 nMod := nNum mod 10;
74 result := result + aTens[nQtnt - 1]; {digit at tenth place}
75 if nMod <> 0 then
76 result := result + '-' + aUnits[nMod] {digit at unit place}
77 else
78 result := result + ' ';
79 end
80 else
81 if result <> '' then
82 result := copy(result, 1, length(result) - 4);
83 end;
84 result := result + aLargeNumWords[nWordIndex]; {add thousand, million etc...}
85 end;
86 var
87 nNum, nIndex: Integer;
88 cStr, cDec: string;
89 lNegative: Boolean;
90 begin
91 result := '';
92 if (nNumber > 999999999999999999.0) then
93 begin
94 showmessage('Sorry this is too large ! larger than the budget of the whole
95 world !!'
96 exit;
97 end;
98 str(nNumber: 34: 15, cStr);
99 lNegative := False;
100 nIndex := pos('-', cStr); {having - sign is negative}
101 if nIndex > 0 then
102 begin
103 lNegative := True;
104 cStr := copy(cStr, nIndex + 1, length(cStr) - nIndex); {trim off minus sign}
105 end;
106 while cStr[1] = ' ' do {trim of spaces}
107 delete(cStr, 1, 1);
108 nIndex := pos('.', cStr); {decimal position}
109 if nIndex = 0 then
110 nIndex := length(cStr) + 1; {if no decimal it must be at the far right}
111 cDec := copy(cStr, nIndex + 1, length(cStr) - nIndex); {digits after decimal
112 point}
113 cStr := copy(cStr, 1, nIndex - 1); {digits before decimal point}
114 nIndex := 0; {index to point the words thousand, million etc.}
115 nNum := length(cStr); {count of digits}
116 while nNum > 0 do
117 begin
118 if nNum < 3 then
119 begin
120 result := Num2EngWords(strToInt(copy(cStr, 1, nNum)), nIndex) + result;
121 cstr := ''; {less than 3 digits means finished}
122 end
123 else
124 begin
125 result := Num2EngWords(strToInt(copy(cStr, nNum - 2, 3)), nIndex) + result;
126 cStr := copy(cStr, 1, nNum - 3); {cut off three rightmost digits}
127 end;
128 nNum := length(cStr); {remaining number of digits}
129 inc(nIndex); {increase the large number's word index}
130 end;
131 result := trim(result) + cDecimal(cDec) + '.'; {finished, add a full stop}
132 if lNegative then
133 result := 'minus ' + result; {if the number is negative add "minus" at first}
134 end;
135
136 //Thanks Mr. KRISHNA SAPKOTA
137 //E-Mail: krishna_sapkota@hotmail.com
138 //for pointing out the misspelled function name in the calling example
139 //below !
140
141 //Calling examples:
142 {nNum:extended or nNum:Double}
143 //nNum:=24693456799398.6078;
144 {Corrected calling function name on Monday May 21, 2001}
145 //label1.caption:=InWords(nNum);
146 {nInt:Integer or nInt:longint}
147 //nInt:=23456
148 //label2.caption:=InWords(nint);
149 //label3.caption:=InWords(2345678965432.30045);
150 //label4.caption:=InWords(896867);
151
152 end.
|