Я набрал это в оболочку python:
>>> 0.1*0.1
0.010000000000000002
Я ожидал, что 0,1 * 0,1 не 0,01, потому что я знаю, что 0,1 в основании 10 является периодическим в основании 2.
>>> len(str(0.1*0.1))
4
Я ожидал получить 20, поскольку я видел 20 символов выше. Почему я получаю 4?
>>> str(0.1*0.1)
'0.01'
Хорошо, это объясняет, почему я len
дает мне 4, но почему str
возвращает '0.01'
?
>>> repr(0.1*0.1)
'0.010000000000000002'
Почему str
round, но repr
нет? (Я прочитал этот ответ, но я хотел бы знать, как они решили, когда str
округляет float, а когда нет)
>>> str(0.01) == str(0.0100000000001)
False
>>> str(0.01) == str(0.01000000000001)
True
Таким образом, это проблема с точностью поплавков. Я думал, что Python будет использовать одиночные префиксы IEEE 754. Поэтому я проверил его следующим образом:
#include <stdint.h>
#include <stdio.h> // printf
union myUnion {
uint32_t i; // unsigned integer 32-bit type (on every machine)
float f; // a type you want to play with
};
int main() {
union myUnion testVar;
testVar.f = 0.01000000000001f;
printf("%f\n", testVar.f);
testVar.f = 0.01000000000000002f;
printf("%f\n", testVar.f);
testVar.f = 0.01f*0.01f;
printf("%f\n", testVar.f);
}
Я получил:
0.010000
0.010000
0.000100
Python дает мне:
>>> 0.01000000000001
0.010000000000009999
>>> 0.01000000000000002
0.010000000000000019
>>> 0.01*0.01
0.0001
Почему Python дает мне эти результаты?
(Я использую Python 2.6.5. Если вы знаете о различиях в версиях Python, я также буду заинтересован в них.)