Samuel
Samuel

Reputation: 6247

how to keep the precision when convert string to double value

For example .

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

actually v =[-97.17312522036036, -97.17312522036036], lost the last 2. How can i keep the same value with the string

Upvotes: 0

Views: 2883

Answers (3)

Ashwini Chaudhary
Ashwini Chaudhary

Reputation: 251061

Use the decimal module:

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

For a string with list case use str.split, str.strip and a list comprehension:

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

From 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'

But for strings with more than sys.float_info.dig significant digits, this isn’t always true:

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

So, if you want to maintain precision for floats that contain more than sys.float_info.dig digits use decimal module.

Upvotes: 4

TerryA
TerryA

Reputation: 60004

Use ast.literal_eval:

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

Using ast.literal_eval is more safe than eval, as the docs mention.

This will give you a list of floats.

Upvotes: 1

Jon Clements
Jon Clements

Reputation: 142206

It's more a display issue, to take your list, use literal_evalinstead:

from ast import literal_eval

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

Then to display, format appropriately:

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

Upvotes: 0

Related Questions