我正在寻找一种能够在单精度和双精度之间翻译的方法。一个例子是将两个整数相除并得到一个浮点结果。这怎么可能呢?
10 7
SWAP S>D D>F S>D D>F F/
F.
> 1.4285714 Ok
参见:http://forth.sourceforge.net/std/dpans/dpans12.htm
Rvm的答案依赖于一个单独的浮点堆栈,尽管标准没有保证,但这是非常常见的。在kForth(一个具有统一的浮点堆栈和双单元浮点数的系统)上,您可以写
: s>f s>d d>f ;
: r/ ( n n -- r ) 'r' for floating-point; 'f' for flags, true/false.
swap s>f rot s>f f/ ;
,这仍然是不标准的:它依赖于关于FP数在堆栈上的宽度的知识。这里有两个可移植的方法:
: r/ ( n1 n2 -- r )
locals| n2 n1 |
n1 s>f n2 s>f f/ ;
: r/ ( n1 n2 -- r )
>r s>f r> s>f f/ ;
尽管你最好的选择是声明环境依赖,然后继续你的方式。一个单独的浮点堆栈确实很有帮助,几乎所有的东西都是这样做的,如果你想把你的代码移植到一个非常罕见的系统上,可以在软件中实现一个FP堆栈。
撇开这些不谈,这里是你的问题的第二个答案:你不需要浮点数来处理分数值(在某些情况下,比如钱,你不仅不需要它们,而且不想要它们)。Forth使您可以很容易地使用固定精度的数字与缩放运算符和自定义数字输出。
一个自定义数字输出的例子:
: .$ ( $ -- )
s>d <# # # [char] . hold #s [char] $ hold #> type ;
100 .$ outputs: $1.00
1525 .$ outputs: $15.25
缩放除法的一个例子:
what's 14 divided by three, with four fractional digits of precision?
14 1000 3 */ result: 4666 -- use a word like .$ to display it as 4.666
(注意n1 n2 n3 */
比n1 n2 * n3 /
更精确——请阅读规范)
: cents ( n -- $ ) ;
: dollars ( n -- $ ) 100 * ;
: $ ( "$" -- $ )
parse-word evaluate d>s ;
what's 14 dollars divided by 3?
14 dollars 3 / .$ outputs: $4.66
what's 42.35 dollars divided by 2?
$ 42.35 2 / .$ outputs: $21.17 (note the loss of a penny!)
关于$
这个词的两个注意事项。首先,它对环境有依赖性,依赖于系统接受带a的双a数。在任何地方,而不是在最后。其次,它接受带a的数字。在中的任何地方,甚至在末尾,但是这些数字仍然被解释为两个小数——例如,$ 4235.
被解释为42美元35美分,而不是四千二千三十五美元。因此,它是草率的,但您可以编写一个更严格且更可移植的解析词。
你可能会说,"这听起来像是额外的工作,浮点数不需要那么多的程序员纪律。"好吧,在你让这种印象僵化之前,请阅读关于浮点运算的每个计算机科学必须知道的东西:-)
(对于sheepez的问题,没有任何远为严肃的ANS Forth系统不支持浮点数。您可能需要加载FP设施,但它们会在那里-"可加载"并不意味着"附加"或"效率较低"。参考您的Forth系统文档)