Decimal(str(myu float))似乎比Decimal(myu float)好,这是怎么回事?

2024-04-19 22:38:44 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在读取一个JSON数据文件,它可能会给我一个float值,比如说,1.1。当我对这个值进行Decimal运算时,我得到了一个疯狂的长数,因为浮点的二进制表示不精确。你知道吗

我理解二进制表示法,而且我同意这样一个观点,即可以用十进制浮点数写的数字不能总是用十进制浮点数来表示。你知道吗

但是如果我先把浮点值串起来,然后用这个字符串做一个十进制值,我就得到了一个没有小的二进制不精确增量的十进制值。你知道吗

我的意思是:

Python 2.7.6 (default, Jan 16 2014, 10:55:32) 
>>> from decimal import Decimal
>>> f = 1.1
>>> d = Decimal(f)
>>> f
1.1
>>> d
Decimal('1.100000000000000088817841970012523233890533447265625')
>>> d = Decimal(str(f))
>>> d
Decimal('1.1')

在将浮点数转换为十进制数之前,对浮点数进行字符串化处理的结果似乎更接近输入的(或从JSON文件读入的)原始十进制数。你知道吗

因此,我的问题是:当字符串化浮点数时,为什么我看不到数字的长尾?python是自动跟踪从JSON解析的原始字符串,还是什么?为什么十进制构造函数不也使用这个技巧呢?你知道吗


Tags: 字符串jsondefault数据文件二进制数字float增量
1条回答
网友
1楼 · 发布于 2024-04-19 22:38:44

浮点的精确值是1.100000000000000088817841970012523233890533447265625。Python并没有以某种方式跟踪原始字符串。当Python用str字符串化它时,它将截断为12位数字。你知道吗

>>> x = 1.0/9
>>> print decimal.Decimal(x) # prints exact value
0.111111111111111104943205418749130330979824066162109375
>>> print x # truncated
0.111111111111

即使使用repr,Python也使用最短的字符串,当使用float解析时,该字符串将舍入到原始浮点值。你知道吗

>>> print repr(x)
0.1111111111111111

如果要解析JSON并获取十进制实例而不是float,可以将parse_float参数传递给load(s)函数:

>>> json.loads('{"foo": 1.234567890123456789}', parse_float=decimal.Decimal)
{u'foo': Decimal('1.234567890123456789')}

上面的调用会导致调用decimal.Decimal来解析JSON字符串中的数字,从而绕过中间调用floatstr时的舍入。您将得到JSON中指定的确切数字。你知道吗

请注意,API区分了用于解析看起来像float的函数、看起来像int的函数和看起来像Infinity-InfinityNaN的函数。如果您希望以相同的方式处理所有3个类别,这可能会有点不方便:

>>> json.loads('{"foo": 1.234567890123456789}',
...            parse_float=decimal.Decimal,
...            parse_int=decimal.Decimal,
...            parse_constant=decimal.Decimal)
{u'foo': Decimal('1.234567890123456789')}

相关问题 更多 >