python 中的浮点小数
Floating point decimals in python
我有一个 python 脚本,我在其中定义了一个名为 dt
的变量并将其初始化为:dt=0.30
。由于某些特定原因,我不得不将我的 python 脚本转换为 C++ 程序,但这两个程序的编写产生了完全相同的结果。问题是结果在某个时候开始出现偏差。我认为问题的发生是由于 0.03 在 python 中没有二进制浮点数的精确表示;而在 C++ 中 dt=0.30
给出 0.300000000000,而 python 输出到我的文件给出 dt=0.300000011921
。
我真正需要的是一种在 python 中精确地强制 dt=0.30
的方法,这样我就可以将我的 python 结果与我的 C++ 代码进行比较,因为我相信其中的区别它们之间只是这个小差异,过度运行会产生实质性差异。因此,我通过调用 from decimal import *
研究了 python 中的 decimal
算法,但我无法将 dt
乘以任何浮点数(我需要为计算做在代码中)。有谁知道在不使用 'decimal floating point' 环境的情况下强制 dt 精确到 0.30 的简单方法?
我没有你的上下文,但试试这个:
$ python
> from decimal import Decimal
> dt = Decimal('0.30')
> sum = Decimal(0)
> for _ in range(1000000000): sum += dt
> sum
Decimal('30000000.00')
请注意 Decimal
是用 字符串 调用的。
检查例如差异:
> Decimal(0.30)
Decimal('0.299999999999999988897769753748434595763683319091796875')
> Decimal('0.30')
Decimal('0.30')
如果你的C编译器的printf
运行时支持十六进制浮点输出,这里有一个测试你可以尝试看看文本转换函数之间的区别:
Python:
Python 2.7.10 (default, Aug 24 2015, 14:04:43)
[GCC 4.2.1 Compatible Apple LLVM 6.1.0 (clang-602.0.53)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> a = float(0.3)
>>> a.hex()
'0x1.3333333333333p-2'
C:
#include <stdio.h>
int main(void)
{
float x = 0.3;
printf("%a\n", x);
return 0;
}
编译后的 C 程序的输出:
0x1.333334p-2
请注意,输出中的 units-last-place (ULP) 相差 1,并且 Python 生成的浮点数看起来像一个 IEEE double。
ULP 存在细微差异是正常的。它只是向您展示了运行时库如何转换浮点数和处理舍入方面的差异。
或者,您可以在 Python 中打印十六进制浮点数并将它们用作 C 源代码中的常量:
#include <stdio.h>
int main(void)
{
float y = 0x1.333334p-2;
printf("%f\n", y);
return 0;
}
或者:
#include <stdio.h>
int main(void)
{
float y = 0x1.333334p-2;
double z = 0x1.3333333333333p-2;
printf("y = %f\n", y);
printf("z = %f\n", z);
return 0;
}
输出:
y = 0.300000
z = 0.300000
我有一个 python 脚本,我在其中定义了一个名为 dt
的变量并将其初始化为:dt=0.30
。由于某些特定原因,我不得不将我的 python 脚本转换为 C++ 程序,但这两个程序的编写产生了完全相同的结果。问题是结果在某个时候开始出现偏差。我认为问题的发生是由于 0.03 在 python 中没有二进制浮点数的精确表示;而在 C++ 中 dt=0.30
给出 0.300000000000,而 python 输出到我的文件给出 dt=0.300000011921
。
我真正需要的是一种在 python 中精确地强制 dt=0.30
的方法,这样我就可以将我的 python 结果与我的 C++ 代码进行比较,因为我相信其中的区别它们之间只是这个小差异,过度运行会产生实质性差异。因此,我通过调用 from decimal import *
研究了 python 中的 decimal
算法,但我无法将 dt
乘以任何浮点数(我需要为计算做在代码中)。有谁知道在不使用 'decimal floating point' 环境的情况下强制 dt 精确到 0.30 的简单方法?
我没有你的上下文,但试试这个:
$ python
> from decimal import Decimal
> dt = Decimal('0.30')
> sum = Decimal(0)
> for _ in range(1000000000): sum += dt
> sum
Decimal('30000000.00')
请注意 Decimal
是用 字符串 调用的。
检查例如差异:
> Decimal(0.30)
Decimal('0.299999999999999988897769753748434595763683319091796875')
> Decimal('0.30')
Decimal('0.30')
如果你的C编译器的printf
运行时支持十六进制浮点输出,这里有一个测试你可以尝试看看文本转换函数之间的区别:
Python:
Python 2.7.10 (default, Aug 24 2015, 14:04:43)
[GCC 4.2.1 Compatible Apple LLVM 6.1.0 (clang-602.0.53)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> a = float(0.3)
>>> a.hex()
'0x1.3333333333333p-2'
C:
#include <stdio.h>
int main(void)
{
float x = 0.3;
printf("%a\n", x);
return 0;
}
编译后的 C 程序的输出:
0x1.333334p-2
请注意,输出中的 units-last-place (ULP) 相差 1,并且 Python 生成的浮点数看起来像一个 IEEE double。
ULP 存在细微差异是正常的。它只是向您展示了运行时库如何转换浮点数和处理舍入方面的差异。
或者,您可以在 Python 中打印十六进制浮点数并将它们用作 C 源代码中的常量:
#include <stdio.h>
int main(void)
{
float y = 0x1.333334p-2;
printf("%f\n", y);
return 0;
}
或者:
#include <stdio.h>
int main(void)
{
float y = 0x1.333334p-2;
double z = 0x1.3333333333333p-2;
printf("y = %f\n", y);
printf("z = %f\n", z);
return 0;
}
输出:
y = 0.300000
z = 0.300000