将字符串转换为双精度值时如何保持精度

问题描述:

例如。将字符串转换为双精度值时如何保持精度

s='[-97.173125220360362, -97.173125220360362]' 
v=eval(s) 

实际上V = [ - 97.17312522036036,-97.17312522036036],失去了最后的2.如何能保持相同的值以字符串

使用decimal模块:

>>> import decimal 
>>> decimal.Decimal('-97.173125220360362') 
Decimal('-97.173125220360362') 

对于列表大小写使用str.split,str.strip和列表理解的字符串:

>>> s = '[-97.173125220360362, -97.173125220360362]' 
>>> [decimal.Decimal(x) for x in s.strip('[]').split(',')] 
[Decimal('-97.173125220360362'), Decimal('-97.173125220360362')] 

docs

>> import sys 
>>> sys.float_info.dig 
15 
>>> s = '3.14159265358979' # decimal string with 15 significant digits 
>>> format(float(s), '.15g') # convert to float and back -> same value 
'3.14159265358979' 

但对于超过sys.float_info.dig显著数字字符串,这并不总是正确的:

>>> 
>>> s = '9876543211234567' # 16 significant digits is too many! 
>>> format(float(s), '.16g') # conversion changes value 
'9876543211234568' 

所以,如果你想保持精度浮点数是包含多于sys.float_info.dig的数字使用decimal模块。

+0

在这种情况下 - 更多的显示问题... '格式(float(their_string),'.17g'))'很好... –

+0

对不起,其实我想在列表上工作。这就是为什么我使用'eval' – Samuel

+0

@JonClements但是如果小数点后的数字位数未知的情况下呢? –

使用ast.literal_eval

import ast 
s = '[-97.173125220360362, -97.173125220360362]' 
print ast.literal_eval(s) 

使用ast.literal_evaleval更安全,因为文档提到。

这会给你一个浮动列表。

+0

这给我比字符串更精确。 – Samuel

+2

在这种情况下,普通的“浮点”值是足够好的,在这种情况下没有使用“小数”的点,或者在值被转换为“浮点数”后,它们不会出现转换为“小数”的点。 – Duncan

+0

@Samuel啊,如果你不想要那么多,那么你可以只做'map(float,ast.literal_eval(s))' – TerryA

它更像是一个显示问题,把你的列表,使用literal_eval代替:

from ast import literal_eval 

s= '[-97.173125220360362, -97.173125220360362]' 
items = literal_eval(s) 
# [-97.17312522036036, -97.17312522036036] 

然后显示,格式正确:

as_strings = [format(el, '.17g') for el in items] 
# ['-97.173125220360362', '-97.173125220360362'] 
+0

我需要使用该值,而不仅仅是显示 – Samuel

+0

@Samuel然后你只使用值....你可以显示它为'3',它仍然是'3.499912' - 它如何显示是不同的... –

+0

但是'eval'可以给出与'literal_eval'在'.17g'相同的显示' – Samuel