Схема - «неточная» концепция в числовой башне R5RS - PullRequest
2 голосов
/ 10 февраля 2011

Размышляя о способе реализации Scheme R5RS, я озадачился следующим фрагментом R5RS (стр. 22-23):

(остаток -13 -4) ==> -1
(остаток -13 -4.0) ==> -1.0; неточное

(lcm 32 -36) ==> 288
(см 32,0 -36) ==> 288,0; неточное

(знаменатель (/ 6 4)) ==> 2
(знаменатель (точный-> неточный (/ 6 4))) ==> 2,0

Если мы поймем, что даже если -4.0, 32.0 и (точный-> неточный (/ 6 4)) неточны, реализация должна «запомнить» их точный эквивалент (-4, 32 и 3/2) в порядке перейти к целочисленному делению, разложению простых множителей и т. д.

В противном случае, как реализация может дать ответы на эти вопросы?

Заранее спасибо за любой свет, который вы могли бы пролить на эту тему! :)

Nicolas

Ответы [ 2 ]

1 голос
/ 10 февраля 2011

Не нужно «запоминать» первоначальную точность аргументов.Он может временно (внутренне) преобразовать числа в точные во время вычисления и пометить результат как неточный, если какой-либо аргумент является неточным.

Примеры:

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

(Последний результат - реализациязависит от числа Racket 5.0.2, запущенного на amd64. Вы получите другие результаты от других реализаций.)

Для скрытых и архивов: необычно выглядящий результат заключается в том, что большинство реализаций используют IEEE754 для неточных чисел, которые (будучи двоичным форматом с плавающей запятой) не могут представлять 0,1 с полной точностью (только десятичный формат с плавающей запятой).

Фактически, если вы используете (inexact->exact 0.1), вы будетене получить 1/10, если ваша реализация не использует десятичную с плавающей точкой.

1 голос
/ 10 февраля 2011

В реализации нет необходимости запоминать точный эквивалент, потому что согласно R5RS можно получить неточный результат, если операция включает в себя неточный операнд.Например:

> (+ -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));
 }

По сути, вышеуказанное дополнение в схеме интерпретируется интерпретатором как:

> (+ -1.0 2.0)
=> 1.0   
...