当前位置: 首页 > 面试题库 >

Python(奇怪)舍入值

关苗宣
2023-03-14
问题内容

这个问题更多是出于好奇。

我正在创建以下数组:

A = zeros((2,2))
for i in range(2):
    A[i,i] = 0.6
    A[(i+1)%2,i] = 0.4
print A

>>>
   [[ 0.6  0.4]
   [ 0.4  0.6]]

然后,打印它:

for i,c in enumerate(A):
    for j,d in enumerate(c):
        print j, d

但是,如果删除j,则会得到:

>>>
0 0.6
1 0.4
0 0.4
1 0.6

但是,如果我从for中删除j,则会得到:

(0, 0.59999999999999998)
(1, 0.40000000000000002)
(0, 0.40000000000000002)
(1, 0.59999999999999998)

是因为我使用0.6创建矩阵的方式吗?它如何代表内部真实价值?


问题答案:

这里发生了一些不同的事情。

首先,Python有两种将对象转换为字符串的机制,称为reprstr
repr应该提供“忠实”的输出,从而(理想情况下)可以轻松轻松地精确地重新创建该对象,同时str旨在提供更易于理解的输出。对于Python之前的版本(包括Python
3.1),请repr提供足够的数字来完全确定float的值(这样,对返回字符串进行评估就可以准确返回该float),同时str
舍入到小数点后12位;这会隐藏不正确的效果,但是意味着两个非常接近的不同浮点数最终可能具有相同的str值-不会发生repr。打印对象时,str该对象。相反,当您仅在解释器提示处对表达式求值时,将获得repr


例如(此处使用Python 2.7):

>>> x = 1.0 / 7.0
>>> str(x)
'0.142857142857'
>>> repr(x)
'0.14285714285714285'
>>> print x  # print uses 'str'
0.142857142857
>>> x  # the interpreter read-eval-print loop uses 'repr'
0.14285714285714285

但是,从您的角度来看,有些混乱,我们得到:

>>> x = 0.4
>>> str(x)
'0.4'
>>> repr(x)
'0.4'

这似乎与您在上面看到的内容不太吻合,但是我们将在下面再介绍。

要记住的第二件事是,在第一个示例中,您要打印两个单独的项目,而在第二个示例中(已j删除),您要打印一个项目:长度为2的元组。当使用转换一个元组以进行打印时str,Python仍然使用该元组repr
元素 的字符串表示形式:

>>> x = 1.0 / 7.0
>>> print x, x  # print x twice;  uses str(x)
0.142857142857 0.142857142857
>>> print(x, x)  # print a single tuple; uses repr(x)
(0.14285714285714285, 0.14285714285714285)

这就解释了为什么在两种情况下您都看到不同的结果,即使基础浮点数相同。

但是,还有最后一个难题。在Python> = 2.7中,我们在上面看到对于特定的float
0.4,该float的strrepr相同。那么,哪里0.40000000000000002来的呢?好吧,这里没有Python浮点数:因为您是从NumPy数组中获取这些值的,所以它们实际上是类型numpy.float64

>>> from numpy import zeros
>>> A = zeros((2, 2))
>>> A[:] = [[0.6, 0.4], [0.4, 0.6]]
>>> A
array([[ 0.6,  0.4],
       [ 0.4,  0.6]])
>>> type(A[0, 0])
<type 'numpy.float64'>

2.7)旨在提供最短的字符串,而该字符串仍可以准确表示浮点数,而NumPy只是基于将基础值四舍五入为17个有效数字来输出字符串。回到0.4上面的示例,这是NumPy的工作:

>>> from numpy import float64
>>> x = float64(1.0 / 7.0)
>>> str(x)
'0.142857142857'
>>> repr(x)
'0.14285714285714285'
>>> x = float64(0.4)
>>> str(x)
'0.4'
>>> repr(x)
'0.40000000000000002'

因此,这三件事共同可以解释您所看到的结果。请放心,这完全是表面上的:底层浮点值没有任何改变;它只是由四个不同的可能组合显示方式不同str,并repr为两种类型:floatnumpy.float64

Python教程提供了有关如何存储和显示Python浮点数的更多详细信息,以及一些潜在的陷阱。对这些问题的答案这太问题对之间的区别的详细信息strrepr



 类似资料:
  • 问题内容: 我是Python的初学者,我有一个问题。 为什么用奇数整数部分四舍五入像5.5、7.5((任何).5)这样的数字正确工作(规则5/4),但是用同一个函数将非奇数整数部分像(任何).5进行四舍五入只返回整数部分?(但是,如果我们在该十进制数上加上一个像0.000000001这样的小数字,它将正常工作) 我的意思是下一个: 返回10,这是正确的。但 返回8,这是不正确的。和 返回9。 为什

  • 我是Python的初学者,我有一个问题。 为什么舍入像5.5、7.5、(anyther).5这样的数字用奇数部分应用是正确的(规则5/4),但是用相同的函数舍入像(anyther).5这样的数字用非奇数部分只返回一个整数部分?(但是如果我们在这个十进制数字上加上一个小数字,比如0.00000000001,它就能正常工作了) 我是说下一个: 返回10,它是正确的。但是

  • 问题内容: 每当我在控制台中输入错误或出错时,都会出现以下消息: 我同时使用Anaconda安装了Python 2.7和3.3。我想知道这是否正常还是python 2.7和3.3之间存在冲突 问题答案: 假设您使用的是ubuntu,这是相关的错误报告https://bugs.launchpad.net/ubuntu/+source/python3.3/+bug/1192890 您需要修补/etc/

  • 问题内容: 这是目录树: 在main.go中: 在client_test.go中: 错误: 我已经阅读了如何在golang中使用自定义软件包?而且我认为我有和这个人一样的解决方案,但是我只是不知道如何解决这个问题。请帮忙。 去环境: 问题答案: 命令去,测试包。 名称与文件模式“ * _test.go”匹配的文件可以包含测试函数,基准函数和示例函数。 不要使用保留名称。例如,将与贯穿始终。

  • 问题内容: 我不了解python中列表的行为: 为什么一个元素的分配影响另一个元素?感谢您的回答! 问题答案: 当您将一个列表相乘时,它会复制对该列表的引用,但不会创建该列表的副本。由于列表是可变的,因此在更改列表时,所有对其引用的引用都会更改。 用ASCII术语来说: 您可以清楚地看到更改list3将同时影响两个位置。 如果要创建可变长列表而不复制引用,则应执行以下操作: 在这里,我们使用列表理

  • 问题内容: 我只是在重新阅读Python 3.0的新增功能,它指出: 函数的舍入策略和返回类型已更改。现在,精确的中途案例将舍入到最接近的偶数结果,而不是从零舍入。(例如,round(2.5)现在返回2而不是3。) 以及关于round的文档: 对于支持的内置类型,将值四舍五入为乘幂n的最接近10的倍数;如果两个倍数相等接近,则四舍五入取整为偶数选择 因此,在v2.7.3下: 如我所料 但是,现在在