Я работаю над интерпретатором lisp и реализую рациональные числа. Я думал, что у них есть преимущество над удвоениями, чтобы иметь возможность представлять числа, такие как 1/3. Я сделал несколько расчетов для сравнения результатов. Я был удивлен результатамидвойная точность и десятичные знаки перидока
с двойниками
(* 3.0 (/ 1.0 3.0)) -> 1
(* 3.0 (/ 4.0 3.0)) -> 4
(* 81.0 (/ 1.0 81.0)) -> 1
с коэффициентами:
(* 3 (/ 1 3)) -> 1
(* 3 (/ 4 3)) -> 4
(* 81 (/ 1 81)) -> 1
Почему результаты операций с плавающей точкой точные? Должна быть потеря точности. двойники не могут хранить бесконечное количество цифр. Или мне что-то не хватает?
Я проверил быструю проверку с помощью небольшого C-приложения. Тот же результат.
#include <stdio.h>
int main()
{
double a1 = 1, b1 = 3;
double a2 = 1, b2 = 81;
printf("result : %f\n", a1/b1 * b1);
printf("result : %f\n", a2/b2 * b2);
return 0;
}
Выход:
результат: 1,000000
результат: 1,000000
MFG
Martin
Попробуйте '% .20f'. Двойные значения точности точны примерно до 15 знаков после запятой, даже если они не точны. –
[Прочитайте это сначала, пожалуйста] (http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html). –
Может ли компилятор заметить деление и умножение и, таким образом, сделать его недействительным (или переупорядочением порядка операции) для вас? – David