2007. június 30., szombat
Converting Numbers to words
Problem/Question/Abstract:
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:
unit Inwordsu;
interface
uses SysUtils, Dialogs;
function InWords(const nNumber: Extended): string;
implementation
function InWords(const nNumber: Extended): string;
const
aUnits: array[0..9] of string = ('', 'one ', 'two ', 'three ', 'four ', 'five ',
'six ', 'seven ', 'eight ', 'nine ');
//Local function to convert decimal portion
function cDecimal(const cDecDitxt: string): string;
var
len, x, n: Integer;
nNumber: string[17];
begin
result := '';
nNumber := cDecDitxt;
//cut off Zeros to the right
while copy(nNumber, length(nNumber), 1) = '0' do
delete(nNumber, length(nNumber), 1);
len := length(nNumber);
//No need to convert if it is all zeros
if len = 0 then
exit;
//Start conversion !
for x := 1 to len do
begin
n := strToint(copy(nNumber, x, 1));
if n = 0 then
result := result + 'zero '
else
result := result + aUnits[n];
end;
if result <> '' then
result := ' decimal ' + trim(result);
end;
//Local function to convert the whole number portion
function Num2EngWords(const nNumber, nWordIndex: integer): string;
const
aLargeNumWords: array[0..5] of string = ('', 'thousand, ', 'million, ',
'billion, ', 'trillion, ', 'quadrillion, ');
aTens: array[0..8] of string = ('', 'twenty', 'thirty', 'forty', 'fifty', 'sixty',
'seventy', 'eighty', 'ninety');
aTwenties: array[10..19] of string = ('ten ', 'eleven ', 'twelve ', 'thirteen ',
'fourteen ', 'fifteen ', 'sixteen ', 'seventeen ', 'eighteen ', 'nineteen ');
var
nQtnt, nNum, nMod: Integer;
begin
result := '';
if nNumber < 1 then
exit;
nNum := nNumber;
if nNumber > 99 then
begin
//Pick up hundreds and leave others
nQtnt := nNum div 100;
nNum := nNum mod 100;
result := aUnits[nQtnt] + 'hundred and ';
end;
case nNum of
1..9: result := result + aUnits[nNum]; {one to nine}
10..19: result := result + aTwenties[nNum]; {ten to nineteen}
20..99:
begin
nQtnt := nNum div 10;
nMod := nNum mod 10;
result := result + aTens[nQtnt - 1]; {digit at tenth place}
if nMod <> 0 then
result := result + '-' + aUnits[nMod] {digit at unit place}
else
result := result + ' ';
end
else
if result <> '' then
result := copy(result, 1, length(result) - 4);
end;
result := result + aLargeNumWords[nWordIndex]; {add thousand, million etc...}
end;
var
nNum, nIndex: Integer;
cStr, cDec: string;
lNegative: Boolean;
begin
result := '';
if (nNumber > 999999999999999999.0) then
begin
showmessage('Sorry this is too large ! larger than the budget of the whole world !!');
exit;
end;
str(nNumber: 34: 15, cStr);
lNegative := False;
nIndex := pos('-', cStr); {having - sign is negative}
if nIndex > 0 then
begin
lNegative := True;
cStr := copy(cStr, nIndex + 1, length(cStr) - nIndex); {trim off minus sign}
end;
while cStr[1] = ' ' do {trim of spaces}
delete(cStr, 1, 1);
nIndex := pos('.', cStr); {decimal position}
if nIndex = 0 then
nIndex := length(cStr) + 1; {if no decimal it must be at the far right}
cDec := copy(cStr, nIndex + 1, length(cStr) - nIndex); {digits after decimal point}
cStr := copy(cStr, 1, nIndex - 1); {digits before decimal point}
nIndex := 0; {index to point the words thousand, million etc.}
nNum := length(cStr); {count of digits}
while nNum > 0 do
begin
if nNum < 3 then
begin
result := Num2EngWords(strToInt(copy(cStr, 1, nNum)), nIndex) + result;
cstr := ''; {less than 3 digits means finished}
end
else
begin
result := Num2EngWords(strToInt(copy(cStr, nNum - 2, 3)), nIndex) + result;
cStr := copy(cStr, 1, nNum - 3); {cut off three rightmost digits}
end;
nNum := length(cStr); {remaining number of digits}
inc(nIndex); {increase the large number's word index}
end;
result := trim(result) + cDecimal(cDec) + '.'; {finished, add a full stop}
if lNegative then
result := 'minus ' + result; {if the number is negative add "minus" at first}
end;
//Thanks Mr. KRISHNA SAPKOTA
//E-Mail: krishna_sapkota@hotmail.com
//for pointing out the misspelled function name in the calling example
//below !
//Calling examples:
{nNum:extended or nNum:Double}
//nNum:=24693456799398.6078;
{Corrected calling function name on Monday May 21, 2001}
//label1.caption:=InWords(nNum);
{nInt:Integer or nInt:longint}
//nInt:=23456
//label2.caption:=InWords(nint);
//label3.caption:=InWords(2345678965432.30045);
//label4.caption:=InWords(896867);
end.
Feliratkozás:
Megjegyzések küldése (Atom)
Nincsenek megjegyzések:
Megjegyzés küldése