Number to String

Here's a base that will go up to a million. You can expand it past there if you like. Give credit where credit is due, and dont resell the code!


unit uNum2Str;

 

// Possible enhancements

// Move strings out to resource files

// Put in a general num2str utility

 

interface

 

function Num2Dollars( dNum: double ) : String;

 

implementation

 

uses SysUtils;

 

function LessThan99( dNum: double ) : String; forward;

 

// floating point modulus

function FloatMod( i,j: double ): double;

begin

  result := i - (Int(i/j) * j);

end;

 

function Hundreds( dNum: double ) : String;

var

  workVar: double;

begin

  if ( dNum < 100 ) or ( dNum > 999 ) then

  raise Exception.Create( 'hundreds range exceeded' );

 

  result := '';

 

  workVar := Int( dNum / 100 );

  if workVar > 0 then

  result := LessThan99(workVar) + ' Hundred';

end;

 

function OneToNine( dNum: Double ) : String;

begin

  if ( dNum < 1 ) or (dNum > 9 ) then

  raise exception.create( 'onetonine: value out of range' );

 

  result := 'woops';

 

  if dNum = 1 then result := 'One'

  else if dNum = 2 then result := 'Two'

  else if dNum = 3 then result := 'Three'

  else if dNum = 4 then result := 'Four'

  else if dNum = 5.0 then result := 'Five'

  else if dNum = 6 then result := 'Six'

  else if dNum = 7 then result := 'Seven'

  else if dNum = 8 then result := 'Eight'

  else if dNum = 9 then result := 'Nine';

 

end;

 

function ZeroTo19( dNum: double ) : String;

begin

  if (dNum < 0) or (dNum > 19) then

  raise Exception.Create( 'Bad value in dNum' );

 

  result := '';

 

  if dNum = 0 then result := 'Zero'

  else if (dNum <= 1) and (dNum >= 9) then result := OneToNine( dNum )

  else if dNum = 10 then result := 'Ten'

  else if dNum = 11 then result := 'Eleven'

  else if dNum = 12 then result := 'Twelve'

  else if dNum = 13 then result := 'Thirteen'

  else if dNum = 14 then result := 'Fourteen'

  else if dNum = 15 then result := 'Fifteen'

  else if dNum = 16 then result := 'Sixteen'

  else if dNum = 17 then result := 'Seventeen'

  else if dNum = 18 then result := 'Eighteen'

  else if dNum = 19 then result := 'Nineteen'

  else result := 'woops!';

end;

 

function TwentyTo99( dNum: double ) : String;

var

  BigNum: String;

begin

  if ( dNum < 20 ) or ( dNum > 99 ) then

  raise exception.Create( 'TwentyTo99: dNum out of range!' );

 

  BigNum := 'woops';

 

  if dNum >= 90 then BigNum := 'Ninety'

  else if dNum >= 80 then BigNum := 'Eighty'

  else if dNum >= 70 then BigNum := 'Seventy'

  else if dNum >= 60 then BigNum := 'Sixty'

  else if dNum >= 50 then BigNum := 'Fifty'

  else if dNum >= 40 then BigNum := 'Forty'

  else if dNum >= 30 then BigNum := 'Thirty'

  else if dNum >= 20 then BigNum := 'Twenty';

 

  // lose the big num

  dNum := FloatMod( dNum, 10 );

 

  if dNum > 0.00 then

  result := BigNum + ' ' + OneToNine( dNum )

  else

  result := BigNum;

end;

 

function LessThan99( dNum: double ) : String;

begin

  if dNum <= 19 then

  result := ZeroTo19(dNum)

  else

  result := TwentyTo99(dNum);

end;

 

function Num2Dollars( dNum: double ) : String;

var

  centsString: String;

  cents: double;

  workVar: double;

begin

  result := '';

 

  if dNum < 0 then

  raise Exception.Create( 'Negative numbers not supported' );

 

  if dNum > 999999999.99 then

  raise Exception.Create( 'Num2Dollars only supports up to the millions at this point!' );

 

 

 

  cents := (dNum - Int( dNum )) * 100.0;

  if cents = 0.0 then

  centsString := 'and 00/100 Dollars'

  else if cents < 10 then

  centsString := Format( 'and 0%1.0f/100 Dollars', [cents] )

  else

  centsString := Format( 'and %2.0f/100 Dollars', [cents] );

 

  dNum := Int( dNum - (cents / 100.0) ); // lose the cents

 

  // deal with million's

  if (dNum >= 1000000 ) and ( dNum <= 999999999 ) then

  begin

  workVar := dNum / 1000000;

  workVar := Int( workVar );

  if (workVar <= 9) then

  result := ZeroTo19(workVar)

  else if ( workVar <= 99 ) then

  result := LessThan99( workVar )

  else if ( workVar <= 999 ) then

  result := Hundreds( workVar )

  else

  result := 'mill fubar';

 

  result := result + ' Million';

 

  dNum := dNum - ( workVar * 1000000 );

  end;

 

  // deal with 1000's

  if (dNum >= 1000 ) and ( dNum <= 999999.99 ) then

  begin

  // doing the two below statements in one line of code yields some really

  // freaky floating point errors

  workVar := dNum/1000;

  workVar := Int( workVar );

  if (workVar <= 9) then

  result := ZeroTo19(workVar)

  else if ( workVar <= 99 ) then

  result := LessThan99( workVar )

  else if ( workVar <= 999 ) then

  result := Hundreds( workVar )

  else

  result := 'thou fubar';

 

  result := result + ' Thousand';

 

  dNum := dNum - ( workVar * 1000 );

  end;

 

  // deal with 100's

  if (dNum >= 100.00 ) and (dNum <= 999.99) then

  begin

  result := result + ' ' + Hundreds( dNum );

  dNum := FloatMod( dNum, 100 );

  end;

 

  // format in anything less than 100

  if ( dNum > 0) or ((dNum = 0) and (Length( result ) = 0)) then

  begin

  result := result + ' ' + LessThan99( dNum );

  end;

  result := result + ' ' + centsString;

end;

 

end.