This is G o o g l e's cache of http://home.earthlink.net/~neilbawd/number.html.
G o o g l e's cache is the snapshot that we took of the page as we crawled the web.
The page may have changed since that time. Click here for the current page without highlighting.
To link to or bookmark this page, use the following url: http://www.google.com/search?q=cache:588hwfKxlKAC:home.earthlink.net/~neilbawd/number.html+&hl=en&ie=UTF-8


Google is not affiliated with the authors of this page nor responsible for its content.

Number

Number

Wil Baden 1999-02-20

Elizabeth D Rather comp.lang.forth

Many implementations provide "hooks" for the application, ... e.g., retaining the "discarded" high-order part of the last number converted in a place the appl can find it, and providing a way to know how many "decimal places" in a just-converted number.

Unfortunately, ANS Forth doesn't go very far in this direction, because when we studied this situation we found the specific approaches differed so much we were unable to derive a good synthesis.

However, handling user input is normally in a part of the application that is highly platform-dependent (e.g., using a Winxx dialog box, keypad on an embedded system, etc.) so you're already outside the normal scope of the Standard and you may as well make use of whatever your implementation provides in this line.

In SwiftForth, for example, there are two application-layer words for input number conversions:

NUMBER              ( c-addr u -- n | d )
Convert the string to a single-cell integer if no punctuation is found, double-cell integer if punctuated.
NUMBER?             ( c-addr u -- 0 | n 1 | d 2 )
Attempt to convert the string to a number. 0 indicates failure. If the number is punctuated, return 2 with the double result beneath; otherwise, return 1 with the single result beneath.

Both words use DPL to indicate the number of digits to the right of the rightmost punctuation (if any) . It's negative if there was no punctuation. So you can check it to find out whether you got a single or a double, and in the latter case use it for scaling if desired. If it was a single and you are concerned about possible overflow, the discarded high-order part may be found in NH.

TEXT

Coded by Wil Baden from Elizabeth D. Rather's description. NUMBER? is used to check if a string is numeric, so "bad" punctuation is rejected.

DPL                 ( -- addr )
User variable containing the number of places after the decimal point for numeric input conversion.
NH                  ( -- addr )
Variable for the high-order part of a single number.
Is-Num-Punct        ( c -- flag )
Test character for numeric punctuation.
NUMBER?             ( str len -- 0 | num 1 | num . 2 )
Convert a string to a number. This version rejects bad punctuation.
'NUMBER             ( -- addr )
Variable for xt for number conversion.
NUMBER              ( str len -- n | n . )
Convert a string to a number in the current base using 'NUMBER. Error when string is not a number.
(NUMBER)            ( str len -- n | n . )
The default NUMBER routine.
Program Text 1
VARIABLE DPL 
VARIABLE NH

\  Numeric Punctuation  :  + , - . /  test.
: Is-Num-Punct      ( c -- flag )
    DUP [CHAR] : = SWAP [CHAR] + - 5 U< OR ;

\  Check that string is a number.

: NUMBER?           ( str len -- 0 | num 1 | num . 2 )
    -1 DPL !
    \  Reject empty string.
    DUP 0= IF  2DROP 0 EXIT  THEN
    OVER C@ [CHAR] - =  DUP NH !  1 AND /STRING
        \  Reject lone minus sign.
        DUP 0= IF  2DROP 0 EXIT  THEN
        \  Reject double minus sign.
        OVER C@ [CHAR] - = IF  2DROP 0 EXIT  THEN
        \  Reject lone punctuation.
        DUP 1 = IF OVER C@ Is-Num-Punct
            IF  2DROP 0 EXIT THEN
        THEN
        0 0 2SWAP                   ( num . str len)
        BEGIN  >NUMBER DUP WHILE
               OVER C@ Is-Num-Punct
               \  Reject successive punctuations.
               OVER DPL @ <> AND
        WHILE  1 /STRING  DUP DPL !
        REPEAT THEN                 ( num . str len)
    ?DUP AND IF                     ( num . str)
        C@ BL - IF  2DROP  0 EXIT  THEN
    THEN                            ( num .)
    NH @ IF  DNEGATE  THEN
    DPL @ 0< IF  NH !  1  ELSE  2  THEN ;

VARIABLE 'NUMBER

: NUMBER  'NUMBER @ EXECUTE ;

: (NUMBER)  NUMBER? 0= ABORT" ? " ;

' (NUMBER) 'NUMBER !


Go back to Neil Bawd's home page.