Схема - "неточная" концепция в числовой башне R5RS
Размышляя о том, как реализовать Scheme R5RS, я озадачился следующим фрагментом R5RS (стр. 22-23):
(остаток -13 -4) ==> -1
(остаток -13 -4,0) ==> -1,0; неточный(лкм 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), чтобы перейти к целочисленное деление, разложение простых факторов и т. д.?
В противном случае, как реализация может дать ответы на эти вопросы?
Заранее спасибо за любой свет, который вы можете пролить на эту тему!:)
никола
2 ответа
Для реализации нет необходимости запоминать точный эквивалент, потому что согласно R5RS можно получить неточный результат, если операция включает в себя неточный операнд. Например:
> (+ -1.0 2)
=> 1.0
Внутренне, переводчик может обновить 2
к float
и вызвать операцию сложения для 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
При этом не нужно "запоминать" первоначальную точность аргументов. Он может временно (внутренне) преобразовать числа в точные во время вычисления и пометить результат как неточный, если какой-либо аргумент является неточным.
Примеры:
(denominator 1/10) ; 10
(denominator 0.1) ; 3.602879701896397e+16
(Последний результат зависит от реализации. Число, которое я привел, взято из Racket 5.0.2, работающего на amd64. Вы получите другие результаты от других реализаций.)
Для тайников и архивов: необычно выглядящий результат состоит в том, что большинство реализаций используют IEEE 754 для неточных чисел, которые (будучи двоичным форматом с плавающей запятой) не могут представлять 0,1 с полной точностью (может только десятичный формат с плавающей запятой).
На самом деле, если вы используете (inexact->exact 0.1)
, вы не получите 1/10
, если ваша реализация не использует десятичную с плавающей точкой.