关于C++:Python中的浮点小数

Floating point decimals in python

本问题已经有最佳答案,请猛点这里访问。

我有一个python脚本,其中定义了一个名为dt的变量,并对其进行初始化:dt=0.30。由于某些特定的原因,我不得不将我的Python脚本转换成C++程序,但是编写了两个程序来生成完全相同的结果。问题是结果在某一点上开始偏离。我相信问题的发生是因为0.03在Python中没有二进制浮点的精确表示;而在C++ EDCOX1中,1给出了0.300000000000,Python输出到我的文件中给出了EDCOX1×3。

我真正需要的是一种在Python中精确地强制EDCOX1 1的方法,这样我就可以将我的Python结果与我的C++代码进行比较,因为我相信它们之间的差别仅仅是在这个小的差异中,它们之间的差异会产生很大的差异。因此,我通过调用from decimal import *来研究python中的decimal算法,但是我不能将dt乘以任何浮点数(我需要在代码中进行计算)。有没有人知道一种简单的方法,不使用"十进制浮点"环境就将dt精确地强制为0.30?


如果C编译器的printf运行时支持十六进制浮点输出,下面是一个测试,您可以尝试查看文本转换函数之间的差异:

Python:

1
2
3
4
5
6
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'

丙:

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>

int main(void)
{
  float x = 0.3;

  printf("%a
"
, x);
  return 0;
}

已编译C程序的输出:

1
0x1.333334p-2

注意,输出中的最后一位单位(ulp)相差1,python生成的float看起来像一个ieee double。

有轻微的尺骨差异是正常的。它只是向您展示了运行库在如何转换浮点数和处理舍入方面存在差异。

或者,可以在python中打印十六进制浮点数,并将其用作C源代码中的常量:

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>

int main(void)
{
  float y = 0x1.333334p-2;

  printf("%f
"
, y);
  return 0;
}

或:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>

int main(void)
{
  float y = 0x1.333334p-2;
  double z = 0x1.3333333333333p-2;

  printf("y = %f
"
, y);
  printf("z = %f
"
, z);

  return 0;
}

输出:

1
2
y = 0.300000
z = 0.300000


我没有你的背景,但是尝试一下:

1
2
3
4
5
6
7
$ python
> from decimal import Decimal
> dt = Decimal('0.30')
> sum = Decimal(0)
> for _ in range(1000000000): sum += dt    
> sum
Decimal('30000000.00')

注意,使用字符串调用Decimal

例如,检查差异:

1
2
3
4
> Decimal(0.30)
Decimal('0.299999999999999988897769753748434595763683319091796875')
> Decimal('0.30')
Decimal('0.30')