转换为 2.dp 的浮点数在插入字符串时恢复为原始的小数位数



我创建了以下代码片段,我正在尝试将我的 5 dp DNumber转换为 2 dp 并将其插入字符串中。但是,无论我尝试使用哪种方法,似乎总是将DNumber恢复到原始的小数位数(5)

下面的代码片段:

if key == (1, 1):
    DNumber = '{r[csvnum]}'.format(r=row) 
    # returns 7.65321
    DNumber = """%.2f""" % (float(DNumber))
    # returns 7.65
    Check2 = False              
    if DNumber:
        if DNumber <= float(8):
            Check2 = True                    
        if Check2:
            print DNumber 
            # returns 7.65
            string = 'test {r[csvhello]} TESTHERE test'.format(r=row).replace("TESTHERE", str("""%.2f""" % (float(gtpe)))) 
# returns: test Hello 7.65321 test
            string = 'test {r[csvhello]} TESTHERE test'.format(r=row).replace("TESTHERE", str(DNumber))
# returns: test Hello 7.65321 test

我希望它能回来:test Hello 7.65 test

关于尝试替代方法的任何想法或建议?

似乎您希望将浮点数转换为 2 位小数位字符串,然后再转换回浮点数会给您一个 2 位小数位浮点数。

第一个问题是你的代码实际上并没有在任何地方做到这一点。如果你这样做了,你会得到一些非常接近7.65的东西,而不是7.65321

但更大的问题是,你想做的事情没有任何意义。无论如何,浮点数始终有 53 个二进制数字。如果你把它四舍五入到两个十进制数字(无论你怎么做,包括通过转换为字符串和回来),你实际得到的是一个四舍五入到两个十进制数字,然后四舍五入到53个二进制数字的浮点数。最接近7.65 float不完全是7.65,而是7.650000000000000355271368。 所以,这就是你最终会得到的。这是没有办法的;这是float存储方式所固有的。

但是,您可以为此使用另一种类型: decimal.Decimal .例如:

>>> f = 7.65321
>>> s = '%.2f' % f
>>> d = decimal.Decimal(s)
>>> f, s, d
(7.65321, '7.65', Decimal('7.65'))
或者,

当然,你可以只传递一个字符串而不是一个浮点数(就像你在代码中不小心做的那样),或者你可以记住每次想要输出它时使用.2f格式。


作为旁注,由于您的DNumber最终成为字符串,因此此行没有任何用处:

if DNumber <= 8:

在 Python 2.x 中,比较两个不同类型的值会给你一个一致但武断且毫无意义的答案。在CPython 2.x中,它将永远False.**在不同的Python 2.x实现中,它可能有所不同。在Python 3.x中,它引发了一个TypeError

将其更改为此没有任何帮助:

if DNumber <= float(8):

现在,您不是将strint进行比较,而是将strfloat进行比较。这完全没有意义,并且遵循完全相同的规则。(此外,float(8)的意思与8.0相同,但可读性较差,并且可能更慢。

就此而言,这个:

if DNumber:

。永远是真的。对于数字,if foo检查它是否不为零。对于float值来说,这是一个坏主意(您应该检查它是否在 0 的绝对或相对误差范围内)。但同样,您没有float值;你有一个str.对于字符串,if foo检查字符串是否为非空。所以,即使你从0开始,你的字符串"0.00"也是真的。


* 我在这里假设您使用的是 CPython,在一个使用 IEEE-754 double 作为其 C double 类型的平台上,并且所有这些在字符串和浮点之间来回的额外转换都不会引入任何其他错误。

** 规则稍微简化一下:如果你比较两个数字,它们被转换为可以容纳它们的类型;否则,如果任何一个值None它更小;否则,如果任何一个值是数字,它更小;否则,如果任何一个值是一个数字,它更小;否则,无论哪个类型的名称按字母顺序排列,都更小。

我认为

您正在尝试执行以下操作 - 将格式与getter相结合:

>>> a = 123.456789
>>> row = {'csvnum': a}
>>> print 'test {r[csvnum]:.2f} hello'.format(r=row)
test 123.46 hello

如果您的号码是 7 后跟五位数字,您可能需要尝试:

print "%r" % float(str(x)[:4])

其中 x 是有问题的浮点数。例:

>>>x = 1.11111
>>>print "%r" % float(str(x)[:4])
>>>1.11

最新更新