-2

我创建了以下代码片段,我正在尝试将我的 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

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

4

3 回答 3

4

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

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

但更大的问题是你试图做的事情没有任何意义。无论如何,浮点数总是有 53 个二进制数字。如果将其四舍五入为两位小数(无论您如何操作,包括转换为字符串并返回),您实际得到的是一个浮点数,四舍五入为两位十进制数字,然后四舍五入为 53 个二进制数字。最接近float7.65不是.* 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):

现在,不是将 a 与 a 进行比较,而是将 astr与aint进行比较。这完全一样没有意义,并且遵循完全相同的规则。(此外,与 的含义相同,但可读性较差且可能较慢。)strfloatfloat(8)8.0

就此而言,这是:

if DNumber:

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


* 我在这里假设您在使用 IEEE-754 double 作为其 Cdouble类型的平台上使用 CPython,并且所有这些在 string 和 float 之间来回的额外转换不会引入任何额外的错误。

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

于 2013-10-16T23:01:01.793 回答
1

我认为您正在尝试执行以下操作 - 将格式与 getter 结合起来:

>>> a = 123.456789
>>> row = {'csvnum': a}
>>> print 'test {r[csvnum]:.2f} hello'.format(r=row)
test 123.46 hello
于 2013-10-16T22:56:16.827 回答
0

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

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

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

>>>x = 1.11111
>>>print "%r" % float(str(x)[:4])
>>>1.11
于 2013-10-16T22:55:24.063 回答