2

スキーム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、および(exact-> inexact(/ 6 4))が不正確であっても、実装は次の手順に進むために、それらの正確な同等物(-4、32、および3/2)を「記憶」する必要があることを理解する必要があります。整数除算、素因数分解など?

そうでなければ、実装はどのようにして上記の答えを出すことに成功するでしょうか?

あなたがこの主題に投げることができるどんな光にも前もって感謝します!:)

ニコラス

4

2 に答える 2

1

R5RSによると、演算に不正確なオペランドが含まれている場合、不正確な結果を生成することは問題ないため、実装が正確に同等のものを記憶する必要はありません。例えば:

> (+ -1.0 2)
=> 1.0

内部的には、インタプリタはにアップグレード2して、floatfloatの加算演算を呼び出すことができます。何も覚えておく必要はありません。

/* 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   
于 2011-02-10T10:58:33.997 に答える
1

引数の元の正確さを「覚えている」必要はありません。計算中に一時的に(内部的に)数値を正確に変換し、引数が不正確な場合は結果に不正確のタグを付けることができます。

例:

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

(後者の結果は実装に依存します。引用した数値は、amd64で実行されているRacket 5.0.2からのものです。他の実装とは異なる結果が得られます。)

潜伏者とアーカイブの場合:異常な結果は、ほとんどの実装が不正確な数値にIEEE 754を使用するためです。これは、(2進浮動小数点形式であるため)0.1を完全な精度で表すことができません(10進浮動小数点形式のみが可能です)。

実際、を使用する場合、実装で10進浮動小数点を使用しない限り、(inexact->exact 0.1)は取得されません。1/10

于 2011-02-10T13:56:53.437 に答える