Joh*_*ohn 6 python floating-point-precision
在Python中有关于float(和precision)的底层数据结构的问题:
>>> b = 1.4 + 2.3
>>> b
3.6999999999999997
>>> c = 3.7
>>> c
3.7000000000000002
>>> print b, c
3.7 3.7
>>> b == c
False
Run Code Online (Sandbox Code Playgroud)
似乎b和c的值取决于机器,它们是最接近目标值但不完全相同的数字.我受到监督,我们得到'正确'的数字与'打印',有人告诉我,这是因为打印'谎言',而Python选择告诉我们真相,即显示他们已存储的确切内容.
我的问题是:
1.如何撒谎?例如,在一个函数中,我们取两个值并返回它们是否相同,如果十进制数(精度)未知,我怎么能得到最好的猜测?像上面提到的b和c?有没有明确定义的算法呢?有人告诉我,如果涉及浮点计算,每种语言(C/C++)都会出现这种问题,但他们如何"解决"这个问题呢?
2.为什么我们不能只存储实际数字而不是存储最接近的数字?这是效率的限制还是交易?
非常感谢约翰
对于第一个问题的答案,请查看Python源代码中的以下(稍微压缩)代码:
#define PREC_REPR 17
#define PREC_STR 12
void PyFloat_AsString(char *buf, PyFloatObject *v) {
format_float(buf, 100, v, PREC_STR);
}
void PyFloat_AsReprString(char *buf, PyFloatObject *v) {
format_float(buf, 100, v, PREC_REPR);
}
Run Code Online (Sandbox Code Playgroud)
所以基本上,repr(float)将返回一个格式为17位精度str(float)的字符串,并返回一个12位精度的字符串.正如你可能已经猜到,print使用str()和解释输入变量名称使用repr().只有12位精度,看起来你得到了"正确"的答案,但这只是因为你所期望的和实际值相同,最多12位数.
这是一个区别的快速示例:
>>> str(.1234567890123)
'0.123456789012'
>>> repr(.1234567890123)
'0.12345678901230001'
Run Code Online (Sandbox Code Playgroud)
至于你的第二个问题,我建议你阅读Python教程的以下部分:浮点算术:问题和限制
当你在基数2中存储基数为10的小数而不是任何其他表示时,它归结为效率,更少的内存和更快的浮点运算,但你确实需要处理不精确.
正如JBernardo在评论中指出的那样,这种行为在Python 2.7及更高版本中有所不同,上面教程链接中的以下引用描述了差异(使用0.1作为示例):
在Python 2.7和Python 3.1之前的版本中,Python将此值四舍五入为17位有效数字,给出"0.10000000000000001".在当前版本中,Python显示一个基于最小小数的值,该小数正确地回滚到真正的二进制值,结果只是'0.1'.
| 归档时间: |
|
| 查看次数: |
1068 次 |
| 最近记录: |