program CashText { www.merlyn.demon.co.uk >=2003-12-17 Convert non-negative longint to English words; test carefully for use with real money } ; function Number(const S : string) : longint ; var L : longint ; J : integer ; begin Val(S, L, J) ; if J<>0 then begin Writeln('Error in "', S, '"') ; HALT end ; Number := L end {Number} ; function Small(TC : string ; J : word ; const K : byte) : string ; const Suffix : array [1..3] of string [9] = ('thousand', 'million', 'milliard') ; Name : array [0..19] of string [9] = ('zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen') ; Namety : array [2..9] of string [7] = ('twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety') ; Punc : array [boolean] of char = ' -' ; var S : string ; begin if J=0 then begin Small := TC ; EXIT end ; S := TC ; if J>999 then begin Writeln('J>999 = ', J) ; HALT end {>999} ; if J>99 then begin S := S + Name[J div 100] + ' hundred ' ; J := J mod 100 ; if J>0 then S := S + 'and ' ; end {>99} else if (S>'') and (J>0) and (K=0) then S := S + 'AND ' ; if J>19 then begin S := S + Namety[J div 10] ; J := J mod 10 ; S := S + Punc[J>0] end {>19} ; if J>0 then S := S + Name[J] + #32 ; if K>0 then S := S + Suffix[K] + #32 ; { Can be made faster by using several strings, combining only at the end } Small := S end {Small} ; function TextCash(const L : longint ; const K : byte) : string ; const None : array [boolean] of string [4] = ('NIL ', '') ; begin if L=0 then TextCash := None[K>0] else TextCash := Small(TextCash(L div 1000, Succ(K)), L mod 1000, K) ; end {TextCash} ; procedure Test(const L : longint) ; const S : array [boolean] of string [1] = ('', 's') ; begin Writeln(L:12, ' = ', TextCash(L, 0)+'pound'+S[L<>1]) end {Test} ; var L : longint ; P : integer ; const Tests : array [1..22] of longint = (0, 1, 3, 10, 15, 22, 100, 123, 1000, 1001, 1102, 10000, 12345, 100000, 123456, 1000000, 1234567, 10000000, 12345670, 1000000000, 1023456789, $7FFFFFFF) ; BEGIN ; if ParamCount>0 then begin for P := 1 to ParamCount do Test(Number(ParamStr(P))) ; HALT end ; for P := Low(Tests) to High(Tests) do Test(Tests[P]) ; Write(' CR ? ') ; Readln ; for L := 0 to 1234 do Test(L) ; repeat Write(' Non-negative number, under 2^31 ? ') ; Readln(L) ; if L<0 then BREAK ; Test(L) until false ; END.