How to Convert Numbers to Their English Language Equivalent

Last reviewed: June 27, 1995
Article ID: Q129921
The information in this article applies to:
  • Microsoft FoxPro for Windows, versions 2.5, 2.5a, 2.5b, 2.6, 2.6a
  • Microsoft FoxPro for MS-DOS, versions 2.0, 2.5, 2.5a, 2.5b, 2.6, 2.6a
  • Microsoft FoxPro for Macintosh, versions 2.5b, 2.5c, 2.6a

SUMMARY

This article shows by example how to display a numeric value in its English language equivalent. For example, in a program that prints checks, you can use this technique to print the value $123.45 on the check as:

   One Hundred Twenty Three Dollars and Forty Five Cents

MORE INFORMATION

The following code example takes the total number of digits to the left of the decimal point of a given number and breaks them into groups of three that include a ones place, a teens place, and a hundreds place.

For example, in the number 123,456.00, the 1 and the 4 are in the hundreds place and the 2 and the 5 are in the teens place of their respective groups of three. Understanding this principle is the key to understanding the code in this article.

To demonstrate the following code example, open or switch to Microsoft FoxPro and open an empty or new program file (PRG). Enter the following code:

* X defines the number to be converted. This may be any value less * than or equal to 9,999,999,999.00 and greater than or equal to 0. * This upper limit is imposed by FoxPro as any larger numbers are * expressed in scientific notation. X = 1234567812.77

* Determine the string equivalent of the integer portion of X: Z = LTRIM(STR(INT(X)))

* Determine how many places are to the left of the decimal point: W = LEN(Z)

* Determine how many groups of 3 appear to the left of the decimal point: Y = INT((LEN(Z) - 1) / 3)

* Determine how many places to the left of the left-most group of 3: REMAIN = LEN(Z) - (Y * 3)

* Initialize MYTOTAL to null. MYTOTAL is a character variable used * to hold the text equivalent of X. MYTOTAL = ""

* Initialize PLACEHOLDER. PLACEHOLDER is a numeric variable used to * track the position (to the left of the decimal point) of the * current number being converted. PLACEHOLDER = 0

* Initialize two variables that determine the initial of scale of X: BILLION = .F. MILLION = .F.

* Initialize a flag variable for teens so as not to combine the ones value * with the returning text string: TEENS = .F. NEWVAR = ""

* Enter a loop that converts each number contained in X (starting with the * left-most) to its character equivalent. W (originally the number of * places to the left of the decimal point in X) is decremented by one each * time a number within X is converted. DO WHILE W > 0

     DO CASE
          * If REMAIN is 1 then the current number under conversion is in
          * the 'ones place' of the current group of three.
          CASE REMAIN = 1
               * A number is going to be converted, so decrease string
               * length by one:
               W = W - 1
               PLACEHOLDER = PLACEHOLDER+1
               * Set CURRENTNUM to the current number to be converted:
               CURRENTNUM = SUBSTR(Z,PLACEHOLDER,1)
               * Call procedure to convert CURRENTNUM to its text
               * equivalent:
               DO TRANS with CURRENTNUM
               * Determine the scale of CURRENTNUM based on current
               * value of W:
               DO CASE
                    CASE W = 9
                         SCALE = "Billion "
                         * Determine contents of the billion group of
                         * three.
                         NEWVAR = SUBSTR(Z,1,REMAIN)
                         BILLION = .T.
                    CASE W = 6
                         SCALE = "Million "
                         * Determine the contents of the million group of
                         * three. If BILLION is false, this is the
                         * left-most group.
                         IF BILLION = .F.
                              NEWVAR = SUBSTR(Z,1,REMAIN)
                         ELSE
                              NEWVAR = SUBSTR(Z,REMAIN + 1, 3)
                         ENDIF
                         MILLION = .T.
                    CASE W = 3
                         SCALE = "Thousand "
                         * Determine the contents of the thousands group
                         * of three. If MILLION is false, this is the
                         * left-most group.
                         IF MILLION = .F.
                              NEWVAR = SUBSTR(Z,1,REMAIN)
                         ELSE
                              NEWVAR = SUBSTR(Z,REMAIN + 4, 3)
                         ENDIF
                         CASE W = 0
                         SCALE = ""
               ENDCASE
               * Add the returned value (CURRENTNUM) to MYTOTAL:
               MYTOTAL = MYTOTAL + CURRENTNUM
               * If the last group of three (determined above) is full of
               * zeros, add the scale description. (Billion, Million
               * Thousand, and so on.):
               IF NEWVAR<>"000"
                    MYTOTAL = MYTOTAL + SCALE
               ENDIF
               * Set current number position to the "hundreds" place:
               REMAIN = 3
          * If REMAIN is 2, the current number under conversion is in
          * the teens place of the current group of three.
          CASE REMAIN = 2
               * Set NEWVAR to 000 because the current number
               * is in the teens place, which will never have a scale tag
               * attached to it (Billion, Million, and so on):
               NEWVAR = "000"
               * A number is going to be converted, so decrease string
               * length by one:
               W = W - 1
               PLACEHOLDER = PLACEHOLDER+1
               * Set CURRENTNUM to the current number to be converted:
               CURRENTNUM =  SUBSTR(Z,PLACEHOLDER,1)
               * Call procedure to convert CURRENTNUM to its text
               * equivalent:
               DO TRANS2 with CURRENTNUM
               * Add the returned value (CURRENTNUM) to MYTOTAL:
               MYTOTAL = MYTOTAL + CURRENTNUM
               * Set current number position to the ones place:
               REMAIN = 1
          * If REMAIN is 3, the current number under conversion is in
          * the hundreds place of the current group of three.
          CASE REMAIN  =  3
               * Set NEWVAR to 000 because the current number
               * is in the hundreds place, which will never have a scale
               * tag attached to it (Billion, Million, and so on.).
               NEWVAR = "000"
               * A number is going to be converted, so decrease string
               * length by one:
               W = W - 1
               PLACEHOLDER = PLACEHOLDER + 1
               * This is in the 'hundreds place, so set unit to Hundred.
               * This is used in procedure TRANS.
               UNIT = "Hundred "
               * Set CURRENTNUM to the current number to be converted:
               CURRENTNUM = SUBSTR(Z,PLACEHOLDER,1)
               * Call procedure to convert CURRENTNUM to its text
               * equivalent:
               DO TRANS with CURRENTNUM
               * Add the returned value (CURRENTNUM) to MYTOTAL:
               MYTOTAL = MYTOTAL + CURRENTNUM
               * Set current number position to the teens place:
               REMAIN = 2
     ENDCASE
ENDDO PLACEHOLDER = 1 * Reinitialize REMAIN to calculate the cents portion of X: REMAIN = 1 * Determine the integer value of X: INTVAL = INT(X) * Check if the integer portion of X is 0: IF INTVAL <> 0
     * Use the above value to calculate the decimal portion of X and
     * convert it to its character equivalent:
     Z = ALLTRIM(STR(MOD(X,INTVAL)*100))
ELSE
     * The integer portion of X is zero, so add Zero to MYTOTAL
     * and set Z equal to the cents portion of X:
     Z = ALLTRIM(STR(X * 100))
     MYTOTAL = "Zero "
ENDIF * Determine if the cents have a teens place: IF LEN(Z)=2
     * Set Y1 to the teens place value of the cents figure:
     Y1 = LEFT(Z,1)
     * Set Y3 equal to Y1. This is used later to determine whether Y1 was
     * equal to a 1. If it is, then TRANS2 calculates the ones place.
     Y3 = Y1
     * Call procedure to convert teens place of cents figure to its
     * text equivalent:
     DO TRANS2 with Y1
ELSE
     * The teens place of the cents figure is 0, so set Y1 to null:
     Y1 = ""
     * Set Y3 equal to Y1. This is used later to determine whether Y1 was
     * equal to a 1. If it is, TRANS2 will calculate the ones place.
     Y3 = Y1
ENDIF * Set Y2 to the ones place value of the cents figure: Y2 = RIGHT(Z,1) * If Y1 and Y2 are null then there are no cents: IF Y2 = "0" AND EMPTY(Y1)
     Y2 = "No "
ELSE
     * If Y3 is not a 1, determine the text equivalent of
     * the ones place of the cents figure:
     IF Y3 <> "1"
          * Call procedure to convert ones place of cents figure to its
          * text equivalent:
          DO TRANS with Y2
     ELSE
          * If Y3 is a 1, then procedure TRANS2 has already determined the
          * ones place value.
          Y2=""
     ENDIF
ENDIF

* Check for "One dollor" and or "One Cent" for correct return string: IF MYTOTAL == "One "

     IF EMPTY(Y1) .AND. Y2 == "One "
          MYTOTAL = MYTOTAL + "Dollar" + " and " + Y2 + "Cent"
     ELSE
          MYTOTAL = MYTOTAL + "Dollar" + " and " + Y1 + Y2 + "Cents"
     ENDIF
ELSE
     IF EMPTY(Y1) .AND. Y2 == "One "
          MYTOTAL = MYTOTAL + "Dollars" + " and " + Y2 + "Cent"
     ELSE
          MYTOTAL = MYTOTAL + "Dollars" + " and " + Y1 + Y2 + "Cents"
     ENDIF
ENDIF

* Call a wait window that will display the converted value of X:

WAIT WINDOW MYTOTAL

* Procedure TRANS, used to convert numbers in the ones and hundreds * place to their text equivalent: PROCEDURE TRANS PARAMETERS CURRENTNUM DO CASE

     CASE VAL(CURRENTNUM) = 9
          IF REMAIN = 1
               IF TEENS
                    CURRENTNUM = ""
               ELSE
                    CURRENTNUM = "Nine "
               ENDIF
          ELSE
               CURRENTNUM = "Nine " + UNIT
          ENDIF
     CASE VAL(CURRENTNUM) = 8
          IF REMAIN = 1
               IF  TEENS
                    CURRENTNUM = ""
               ELSE
                    CURRENTNUM = "Eight "
               ENDIF
          ELSE
               CURRENTNUM = "Eight " + UNIT
          ENDIF
     CASE VAL(CURRENTNUM) = 7
          IF REMAIN = 1
                IF  TEENS
                    CURRENTNUM = ""
               ELSE
                    CURRENTNUM = "Seven "
               ENDIF
          ELSE
               CURRENTNUM = "Seven " + UNIT
          ENDIF
     CASE VAL(CURRENTNUM) = 6
          IF REMAIN = 1
               IF  TEENS
                    CURRENTNUM = ""
               ELSE
                    CURRENTNUM = "Six "
               ENDIF
          ELSE
              CURRENTNUM = "Six " + UNIT
          ENDIF
     CASE VAL(CURRENTNUM) = 5
          IF REMAIN = 1
               IF  TEENS
                    CURRENTNUM = ""
               ELSE
                    CURRENTNUM = "Five "
               ENDIF
          ELSE
               CURRENTNUM = "Five " + UNIT
          ENDIF
     CASE VAL(CURRENTNUM) = 4
          IF REMAIN = 1
               IF  TEENS
                    CURRENTNUM = ""
               ELSE
                    CURRENTNUM = "Four "
               ENDIF
          ELSE
               CURRENTNUM = "Four " + UNIT
          ENDIF
     CASE VAL(CURRENTNUM) = 3
          IF REMAIN = 1
               IF  TEENS
                    CURRENTNUM = ""
               ELSE
                    CURRENTNUM = "Three "
               ENDIF
          ELSE
               CURRENTNUM = "Three " + UNIT
          ENDIF
     CASE VAL(CURRENTNUM) = 2
          IF REMAIN = 1
               IF  TEENS
                    CURRENTNUM = ""
               ELSE
                    CURRENTNUM = "Two "
               ENDIF
          ELSE
               CURRENTNUM = "Two " + UNIT
          ENDIF
     CASE VAL(CURRENTNUM) = 1
          IF REMAIN = 1
               IF  TEENS
                    CURRENTNUM = ""
               ELSE
                    CURRENTNUM = "One "
               ENDIF
          ELSE
               CURRENTNUM = "One " + UNIT
          ENDIF
     CASE VAL(CURRENTNUM) = 0
          CURRENTNUM = ""
ENDCASE TEENS = .F. RETURN CURRENTNUM

* Procedure TRANS2, used to convert numbers in the teens place to their * text equivalent: PROCEDURE TRANS2 PARAMETERS CURRENTNUM DO CASE

     CASE VAL(CURRENTNUM) = 9
          CURRENTNUM = "Ninety "
     CASE VAL(CURRENTNUM) = 8
          CURRENTNUM = "Eighty "
     CASE VAL(CURRENTNUM) = 7
          CURRENTNUM = "Seventy "
     CASE VAL(CURRENTNUM) = 6
          CURRENTNUM = "Sixty "
     CASE VAL(CURRENTNUM) = 5
          CURRENTNUM = "Fifty "
     CASE VAL(CURRENTNUM) = 4
          CURRENTNUM = "Forty "
     CASE VAL(CURRENTNUM) = 3
          CURRENTNUM = "Thirty "
     CASE VAL(CURRENTNUM) = 2
          CURRENTNUM = "Twenty "
     CASE VAL(CURRENTNUM) = 1
          CURRENTNUM = SUBSTR(Z,PLACEHOLDER,2)
          DO CASE
               CASE CURRENTNUM = "19"
                    CURRENTNUM = "Nineteen "
               CASE CURRENTNUM = "18"
                    CURRENTNUM = "Eighteen "
               CASE CURRENTNUM = "17"
                    CURRENTNUM = "Seventeen "
               CASE CURRENTNUM = "16"
                    CURRENTNUM = "Sixteen "
               CASE CURRENTNUM = "15"
                    CURRENTNUM = "Fifteen "
               CASE CURRENTNUM = "14"
                    CURRENTNUM = "Fourteen "
               CASE CURRENTNUM = "13"
                    CURRENTNUM = "Thirteen "
               CASE CURRENTNUM = "12"
                    CURRENTNUM = "Twelve "
               CASE CURRENTNUM = "11"
                    CURRENTNUM = "Eleven "
               CASE CURRENTNUM = "10"
                    CURRENTNUM = "Ten "
          ENDCASE
          * Set teens flag to true to avoid adding the ones number to the
          * returning text string.
           TEENS = .T.
     CASE VAL(CURRENTNUM) = 0
          CURRENTNUM = ""
ENDCASE RETURN CURRENTNUM


Additional reference words: FoxWin FoxMac FoxDos 2.00 2.50 2.50a 2.50b
2.50c 2.60 2.60a
KBCategory: kbprg kbcode
KBSubcategory: FxprgGeneral


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: June 27, 1995
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.