简体   繁体   中英

Python, Convert Arbitrary List of Floats to Decimals with Most Precision without Rounding Errors

I'm writing code that has to take a bunch of floats in Python and convert them to decimals without any rounding errors but with as much precision as possible. I'm not sure what the best approach to solve this is. Just based on some empirical tests, this seems to work OK:

import math
from decimal import Decimal
numbers = [2400.2, 4800.3, 3000, 1.1 + 2.2, 0.000000000000006, -1.418686791445350, 1.418686791445356666666, 2400.418686791445350]

def orderOfMagnitude(number):
  return math.floor(math.log(abs(number), 10))

for num in numbers:
  places = 14 - orderOfMagnitude(num)
  dec = Decimal(num).quantize(Decimal(f'1.{"0"*places}'))
  print(dec)

output:

2400.20000000000
4800.30000000000
3000.00000000000
3.30000000000000
6.00000000000000E-15
-1.41868679144535
1.41868679144536
2400.41868679145

but of course there could be a counterexample where this doesn't work and there is an error. For example, if I use 15 instead of 14 in the formula for places I get:

2400.200000000000
4800.299999999999
3000.000000000000
3.300000000000000
6.000000000000000E-15
-1.418686791445350
1.418686791445357
2400.418686791445

and you can see the error for 4800.3 .

What is the proper way to convert an arbitrary list of floats to decimals with as much precision as possible without rounding errors? Is this even possible?

Edit: I'm on Windows 10 and Python 3.8 if that makes a difference.

import math
from decimal import Decimal
numbers = [2400.2, 4800.3, 3000, 1.1 + 2.2, 0.000000000000006, -1.418686791445350, 1.418686791445356666666, 2400.418686791445350]

def orderOfMagnitude(number):
  return math.floor(math.log(abs(number), 10))

for num in numbers:
  places = 15 - orderOfMagnitude(num)
  dec = Decimal(num).quantize(Decimal(f'1.{"0"*places}'))
  print(dec)

works well

2400.200000000000
4800.300000000000
3000.000000000000
3.300000000000000
6.000000000000000E-15
-1.418686791445350
1.418686791445357
2400.418686791445

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM