为什么以及如何在Python中截断数值数据?
我这里有两个变量,但我有点困惑,因为当我想把它们作为URL参数发送时,它们的值似乎在变化(精度丢失了)。
让我给你展示一个场景,我在Python解释器中复现了这个问题:
>>> lat = 0.33245794180134
>>> long = 32.57355093956
>>> lat
0.33245794180133997
>>> long
32.57355093956
>>> nl = str(lat)
>>> nl '0.332457941801'
>>> nlo = str(long)
>>> nlo '32.5735509396'
那么发生了什么呢?我该如何确保在把lat
和long
转换成字符串并作为URL查询字符串的一部分发送时,不会失去它们的精确度呢?
为了更清楚地说明情况:
- 这些数据最初是作为浮点数(在一个集合中)从另一个模块传到我的模块的,这个模块是通过计算生成这些数据的。
- 精度在这里非常重要,因为这些数据用于跟踪和监控,错误的值可能导致误报或不必要的警报。
- 没有办法将数据发送到目标引擎(它通过RESTful API监听),而不先把数据转换成字符串(这样我才能把它们放在查询字符串中作为参数)。
所以我需要的是一种将浮点数转换成字符串的最佳方法,以尽量减少精度或信息的损失。
4 个回答
2
str
是用来生成人类可读的表示方式的。它很少会产生与输入值相同或相似的表达式结果。而 repr
则是专门用来做到这一点的。实际上,它就是在交互式环境中用来反馈表达式结果的工具。
不过要注意,浮点数的精度是有限的,无法准确表示某些数字,无论你怎么把它们转成字符串。
3
你可以试着用字符串格式化来获得想要的精度。
>>> lat = 0.33245794180134
>>> lat
0.33245794180134
>>> "%.14f" % lat
'0.33245794180134'
>>>
编辑以加入评论:
>>> '{0:.14f}'.format(lat)
'0.33245794180134'
>>>
4
一般来说,如果你使用 '%.14f' % lat
,你就是在丢失精度。
要想保持浮点数的完整精度,可以使用 repr()
。
举个例子:
>>> lat = 1/3.
>>> lat
0.3333333333333333
>>> str(lat).count('3')
12
>>> ('%.14f' % lat).count('3')
14
>>> repr(lat).count('3')
16
>>>
顺便提一下,你正在使用一个旧版本的Python。
>>> 0.33245794180134 == 0.33245794180133997
True
>>>
在2.7之前的Python版本中,使用 repr(a_float)
会产生17位有效数字,因为这样可以确保 float(repr(a_float)) == a_float
。新的方法是使用最少的数字来保证同样的结果。你可以访问 这个链接,然后按Ctrl-F搜索 repr()
。
如果你是从外部来源获取这些数字,那么在将它们转为浮点数并用14位小数进行序列化时,可能会丢失精度。
如果你是通过计算得到这些数字,那么在用14位小数进行序列化时,也可能会丢失精度。
总结一下:一般来说,如果你使用 '%.14f' % lat,你就是在丢失精度——不是Python的问题,也不是浮点运算的问题,是你的问题。