方案 - R5RS数字塔中的“不精确”概念

时间:2011-02-10 10:06:47

标签: scheme r5rs inexact-arithmetic

在考虑实施Scheme R5RS的方法时,我对以下R5RS的摘录(第22-23页)感到困惑:

  

(余数-13 -4)==> -1
  (余数-13 -4.0)==> -1.0;不精确

     

(lcm 32 -36)==> 288个
  (lcm 32.0 -36)==> 288.0;不精确

     

(分母(/ 6 4))==> 2
  (分母(确切 - >不精确(/ 6 4)))==> 2.0

我们应该理解,即使-4.0,32.0和(确切 - >不精确(/ 6 4))不精确,实现也应该“记住”它们的确切等价(-4,32和3/2)为了进行整数除法,素数因子分解等?

否则,实施如何成功地提供上述答案?

提前感谢您可以投入任何光线! :)

尼古拉斯

2 个答案:

答案 0 :(得分:1)

实现不需要记住确切的等价物,因为根据R5RS,如果操作涉及不精确的操作数,则可以产生不精确的结果。 E.g:

> (+ -1.0 2)
=> 1.0

在内部,解释器可以将2升级为float并调用浮点数的加法运算,无需记住任何内容:

/* Assuming that the interpreter implements primitive operations in C. */
SchemeObject* addInts(SchemeObject* a, SchemeObject* b)
{
    if (a->type == FLOAT || b->type == FLOAT)
    {
        cast_int_value_to_float (a);
        cast_int_value_to_float (b);
        return addFloats (a, b);
    }
    return make_new_int_object (get_int_value (a) + get_int_value (b));
 }

实际上,Scheme中的上述添加内容由解释器处理为:

> (+ -1.0 2.0)
=> 1.0   

答案 1 :(得分:1)

它不必“记住”参数的原始精确性。它可以在计算过程中暂时(内部)将数字转换为精确数字,如果任何参数不准确,则将结果标记为不精确。

示例:

(denominator 1/10)  ; 10
(denominator 0.1)   ; 3.602879701896397e+16

(后者的结果与实现有关。我引用的数字来自在amd64上运行的Racket 5.0.2。你会得到与其他实现不同的结果。)

对于潜伏者和档案馆:看起来很不寻常的结果是因为大多数实现都使用IEEE 754来表示不精确的数字,它们(是一个二进制浮点格式)不能用完全精度表示0.1(只有十进制浮点格式才能)

事实上,如果您使用(inexact->exact 0.1),除非您的实现使用十进制浮点,否则您将无法获得1/10