Python 到 C 浮点不精确
Python to C Floating Point Imprecision
从 Python 中创建的 csv 文件导入浮点数到用 C 编写的程序时,我遇到了一些精度问题。以下代码是我的程序中发生的情况的示例:Python 将 float32 值写入文件(在本例中为 9.8431373e+00),我将其读入字符串并使用 strtof
将其转换回 float32,但结果在最后一个小数位上有所不同。
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char* a;
char x[10] = "9.8431373";
printf("%s\n", x);
float f = strtof(x,&a);
printf("%.7e\n", f);
}
输出:
9.8431373
9.8431377e+00
现在,如果我错了,请纠正我,但是 C 中的 float
对象有 32 位,无论它的浮点数是多少,它都会导致 7 位小数的精度。所以如果我没有声明一个大于浮点数允许的数字,就不会有任何精度错误。
如果我确实声明了一个比 C 中允许的 float 更精确的数字,那么 Python 如何在不更正的情况下将“9.8431373e+00”接受为 Float32? Python 和 C 对 32 位浮点数有不同的标准吗?
Python 默认解释为 double。如果您打包为单精度并再次解包,您会在 Python 中看到相同的问题:
>>> import struct
>>> a = struct.pack('<f', 9.8431373)
>>> b, = struct.unpack('<f', a)
>>> b
9.843137741088867
从根本上说,小数部分 9.8431373 在二进制浮点数中不存在,无论是单精度 (float
) 还是双精度。作为 32 位 float
,您可以获得的最接近的是一个二进制数,相当于大约 9.84313774,而作为 double
,您可以获得的最接近的是一个对应于大约 9.8431373000000004 的数字。
这取决于您和您的编程语言的某种组合,这些数字如何以十进制显示给您。有时它们是圆形的,有时它们是截短的。我不太了解 Python,但我知道它的规则至少与 C 的规则有一点不同,所以你看到最后一位数字相差 1 我并不感到惊讶。
从 Python 中创建的 csv 文件导入浮点数到用 C 编写的程序时,我遇到了一些精度问题。以下代码是我的程序中发生的情况的示例:Python 将 float32 值写入文件(在本例中为 9.8431373e+00),我将其读入字符串并使用 strtof
将其转换回 float32,但结果在最后一个小数位上有所不同。
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char* a;
char x[10] = "9.8431373";
printf("%s\n", x);
float f = strtof(x,&a);
printf("%.7e\n", f);
}
输出:
9.8431373
9.8431377e+00
现在,如果我错了,请纠正我,但是 C 中的 float
对象有 32 位,无论它的浮点数是多少,它都会导致 7 位小数的精度。所以如果我没有声明一个大于浮点数允许的数字,就不会有任何精度错误。
如果我确实声明了一个比 C 中允许的 float 更精确的数字,那么 Python 如何在不更正的情况下将“9.8431373e+00”接受为 Float32? Python 和 C 对 32 位浮点数有不同的标准吗?
Python 默认解释为 double。如果您打包为单精度并再次解包,您会在 Python 中看到相同的问题:
>>> import struct
>>> a = struct.pack('<f', 9.8431373)
>>> b, = struct.unpack('<f', a)
>>> b
9.843137741088867
从根本上说,小数部分 9.8431373 在二进制浮点数中不存在,无论是单精度 (float
) 还是双精度。作为 32 位 float
,您可以获得的最接近的是一个二进制数,相当于大约 9.84313774,而作为 double
,您可以获得的最接近的是一个对应于大约 9.8431373000000004 的数字。
这取决于您和您的编程语言的某种组合,这些数字如何以十进制显示给您。有时它们是圆形的,有时它们是截短的。我不太了解 Python,但我知道它的规则至少与 C 的规则有一点不同,所以你看到最后一位数字相差 1 我并不感到惊讶。