float a = 0.7;
if(a<0.7)
Первая строка выше берет double
0.7
и помещает его в float
, который почти наверняка имеет меньшую точность (так что вы можете потерять информацию).
Вторая строка обновляет float a
до double
(потому что вы сравниваете его с double 0.7
, и это одна из вещей, которые C делает для вас), но в этот момент уже слишком поздно, информация уже исчезла.
Вы можете увидеть этот эффект с:
#include <stdio.h>
int main(void) {
float a = 0.7;
float b = 0.7f;
double c = 0.7;
printf("a %.50g\nb %.50g\nc %.50g\n", a, b, c);
return 0;
}
, который генерирует что-то вроде:
a 0.699999988079071044921875
b 0.699999988079071044921875
c 0.69999999999999995559107901499373838305473327636719
Очевидно, переменная double c
имеет примерно вдвое большую точность (вот почему их часто называют одинарной и двойной точностью), чем обе:
-
double 0.7
втиснуты в переменную float a
; и - переменная
float b
, в которой хранится float 0.7
.
Ни один из них не совпадает с 0.7
из-за способа плавающего числа точек работают, но double
ближе к желаемому значению, следовательно, не равно float
.
Это как налить полное четырехлитровое ведро воды в трехлитровое, а затем снова. Литр, который вы потеряли при переполнении меньшего ведра, волшебным образом не появляется снова: -)
Если вы измените тип своего a
на double
или используете float
литералы, например 0.7f
, вы обнаружите, что все работает лучше, чем вы ожидаете, поскольку в этом случае нет потери точности.
Причина, по которой вы не видите такого же эффекта в Python, заключается в том, что есть один базовый тип для этих значений с плавающей запятой:
>>> x = float(.7)
>>> type(x)
<class 'float'>
>>> type(.7)
<class 'float'>
Из Python документов:
Есть три различных типа numeri c : целые числа, числа с плавающей запятой и комплексные числа. Кроме того, логические значения - это подтип целых чисел. Целые числа имеют неограниченную точность. Числа с плавающей запятой обычно реализуются с использованием double in C.
Следовательно, в этом случае нет потери точности.
использование double
, похоже, подтверждается (слегка переформатировано):
>>> import sys
>>> print(sys.float_info)
sys.float_info(
max=1.7976931348623157e+308,
max_exp=1024,
max_10_exp=308,
min=2.2250738585072014e-308,
min_exp=-1021,
min_10_exp=-307,
dig=15,
mant_dig=53,
epsilon=2.220446049250313e-16,
radix=2,
rounds=1
)
Показатели степени и минимальные / максимальные значения идентичны значениям IEEE754 двойной точности .