python中的浮点小数

Floating point decimals in python

本文关键字:小数 python      更新时间:2023-10-16

我有一个python脚本,在其中我定义了一个名为dt的变量,并将其初始化为:dt=0.30。由于某些特定的原因,我不得不将我的python脚本转换为C++程序,但这两个程序是为了产生完全相同的结果而编写的。问题是,结果在某个时刻开始出现偏差。我认为问题的出现是因为0.03在python中没有二进制浮点的精确表示;而在C++中,dt=0.30给出0.3000000000000,python输出到我的文件给出dt=0.300000011921

我真正需要的是一种在python中精确地强制dt=0.30的方法,这样我就可以将我的python结果与我的C++代码进行比较,因为我相信它们之间的差异只是这个小差异,过度运行会导致实质性的差异。因此,我已经通过调用from decimal import *研究了python中的decimal算法,但我无法将dt与任何浮点数相乘(我需要在代码中进行计算)。有人知道在不使用"十进制浮点"环境的情况下将dt精确到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("%an", x);
  return 0;
}

编译后的C程序输出:

0x1.333334p-2

请注意,输出中的最后一位单位(ULP)相差1,Python生成的浮点值看起来像IEEE双精度。

ULP有微小差异是正常的。它只是向您展示了运行库转换浮点数和处理舍入的方式存在差异。

或者,您可以在Python中打印十六进制浮点,并将它们用作C源中的常量:

#include <stdio.h>
int main(void)
{
  float y = 0x1.333334p-2;
  printf("%fn", y);
  return 0;
}

或者:

#include <stdio.h>
int main(void)
{
  float y = 0x1.333334p-2;
  double z = 0x1.3333333333333p-2;
  printf("y = %fn", y);
  printf("z = %fn", z);
  return 0;
}

输出:

y = 0.300000
z = 0.300000

我没有你的上下文,但试试这个:

$ 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')