首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Forth中输入数字

如何在Forth中输入数字
EN

Stack Overflow用户
提问于 2018-08-06 09:25:59
回答 3查看 834关注 0票数 9

在Basic中有类似于input的东西,在Forth中有类似于scanf("%d")的东西吗?

可能会是这样的:

代码语言:javascript
复制
200 buffer: buf
: input ( -- n ) buf 200 accept 
  some-magic-filter
  buf swap evaluate ;

在上面的代码中,问题是如何定义一个只传递数字的过滤器,而不是任何单词、定义等?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-08-06 23:29:55

标准只指定一个低级别的>NUMBER字来解释整数。使用EVALUATE将字符串转换为数字的OTOH是一种快速而肮脏的方法。要么不用检查使用它(在可信输入的情况下),要么根本不使用它。尝试在EVALUATE之前过滤字符串是个坏主意:它有>NUMBER字本身的成本和较低的重用因子。

NB: >NUMBEREVALUATE都没有检测到数字溢出。

在任何情况下,输入单细胞整数的单词都可以定义如下:

代码语言:javascript
复制
: accept-number ( -- n )
  PAD DUP 80 ACCEPT ( addr u ) StoN ( n )
;

在可信输入的情况下,您可以定义如下所示的StoN

代码语言:javascript
复制
: StoN ( addr u -- x )
  STATE @ ABORT" This naive StoN should not be used in compilation state"
  DEPTH 2- >R
    EVALUATE
  DEPTH 1- R> <> IF -24 THROW THEN
  \ check depth to accept the single-cell numbers only
;

否则(在不可信输入的情况下),您有两个选择:依赖特定Forth系统的特定单词,或者使用一些(可能是您自己的)库。

我使用以下词汇来定义StoN

代码语言:javascript
复制
\ ---
\ The words from Substring Matching library
\ (where length is counted in address units)

: MATCH-HEAD ( a u a-key u-key -- a-right u-right true | a u false ) 
  2 PICK OVER U< IF  2DROP FALSE EXIT THEN 
  DUP >R
  3 PICK R@ COMPARE IF  RDROP FALSE EXIT THEN 
  SWAP R@ + SWAP R> - TRUE
; 

\ ---
\ The words from Literals interpreting library
\ (where prefix 'I-' is shortcut for Interpret)

: I-DLIT ( a u -- x x true | a u false ) 
  2DUP S" -"  MATCH-HEAD >R
  DUP 0= IF  NIP RDROP EXIT THEN 
  0 0 2SWAP >NUMBER NIP IF  RDROP 2DROP FALSE EXIT THEN 
  R> IF  DNEGATE THEN  2SWAP 2DROP TRUE
; 

: I-LIT ( a u -- x true | a u false ) 
  I-DLIT IF  D>S TRUE EXIT THEN  FALSE
;

在此之后,StoN可以定义为:

代码语言:javascript
复制
: StoN ( a u -- x ) I-LIT IF EXIT THEN -24 THROW ;

上述库可以在GitHub上找到:

票数 8
EN

Stack Overflow用户

发布于 2018-08-06 14:18:33

Rosetta码建议使用GForth 0.6.2的代码片段来确定输入字符串是否为数字字符串:

代码语言:javascript
复制
: is-numeric ( addr len -- )
  2dup snumber? ?dup if
   0< if
     -rot type ."  as integer = " .
   else
     2swap type ."  as double = " <# #s #> type
   then
  else 2dup >float if
    type ."  as float = " f.
  else
    type ."  isn't numeric in base " base @ dec.
  then then ;
票数 2
EN

Stack Overflow用户

发布于 2021-06-17 02:39:17

我为Camel Forth构建了一个基本的like #输入词,让基本用户更加熟悉。这需要超过一个人的想象。它从$ACCEPT开始,它可以用于喜欢带有字符串变量或内存块的输入。

数字的定义?这里只针对单个ints,但它是在GForth上编译的。如果转换不好,它会输出真;SNUMBER的相反?

代码语言:javascript
复制
    DECIMAL
    : NUMBER?  ( addr len -- n ?)      \ ?=0 is good conversion
               (          -- addr len) \ bad conversion
               OVER C@ [CHAR] - = DUP >R     \ save flag for later
               IF 1 /STRING THEN             \ remove minus sign
               0 0  2SWAP >NUMBER NIP NIP    \ convert the number
               R> IF SWAP NEGATE SWAP THEN   \ negate if needed
    ;

    : $ACCEPT ( $addr -- ) CR ." ?  "  DUP  1+ 80 ACCEPT  SWAP C!  ;
  
    : #INPUT  ( variable -- )   \ made to look/work like TI-BASIC
              BEGIN
                PAD $ACCEPT        \ $ACCEPT text into temp buffer PAD
                PAD COUNT NUMBER?  \ convert the number in PAD
              WHILE                \ while the conversion is bad do this
                 CR ." Input error "
                 CR DROP
              REPEAT
              SWAP ! ;           \ store the number in the variable

\ USAGE:  VARIABLE X  
\         X #INPUT      
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51704398

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档