在Python中查找双精度中的最低有效数字



我有很多金融数据存储为浮点双精度,我正在努力寻找最低有效位数,以便将数据转换为带指数的整数。

所有数据都是有限的,例如1234.23或0.0001234,但因为它是以双精度存储的,所以它可以是123.23000000001或0.000123399999999等

有没有一个简单或合适的方法来解决这个问题,或者我只能把它搞砸?

您有几个选项,

首先,最好使用stdlibDecimal,而不是内置的float

这修复了大多数与浮动相关的错误,但没有修复臭名昭著的0.1 + 0.2 = 0.3...4

from decimal import Demical
print(0.1 + 0.2)  # 0.30000000000000004
print(Decimal(0.1) + Decimal(0.2))  # 0.3000000000000000166533453694

如果不可能,另一种选择是设置小数点后重复位数的容差。

例如:

import re
repeated_digit_tolerance = 8  # Change to an appropriate value for your dataset
repeated_digit_pattern = re.compile(r"(.)1{2,}")
def longest_repeated_digit_re(s: str):
match = repeated_digit_pattern.search(s)
string = match.string
span = match.span()
substr_len = span[1] - span[0]
return substr_len, string
def fix_rounding(num: float) -> float:
num_str = str(num)
pre_dp = num_str[:num_str.index(".")]
post_dp = num_str[num_str.index(".") + 1:]
repetition_length, string = longest_repeated_digit_re(post_dp)
if repetition_length > repeated_digit_tolerance:
shortened_string = string[:repeated_digit_tolerance-1]
return float(".".join([pre_dp, shortened_string]))
print(0.1 + 0.2) # 0.30000000000000004
print(0.2 + 0.4) # 0.6000000000000001
print(fix_rounding(0.1 + 0.2))  # 0.3
print(fix_rounding(0.2 + 0.4))  # 0.6

这是一个功能完美的代码,但实际上Decimal总是两者中更好的选择,即使它不能正确地执行0.1 + 0.2

这是我使用字符串的拙劣之处。它目前可以满足我的需求,但我还没有完全测试过

print(int_sci_nrotation(0.1+0.2((将返回一个元组(3,-1(

def int_sci_notation(decimal_value):
#decimal value is finite value stored in double precision
#convert to scientific string (cannot prevent E notation so force all numbers to E notation)
tostr = format(decimal_value, ".14E")
#get exponent from string
if tostr[-3] == '-':
exp = -int(tostr[-2:])
else:
exp = int(tostr[-2:])
#get significant figures as an integer
frac = tostr[1:-4].strip('0')
sf = tostr[0]+frac[1:]
#return the integer 'mantissa' and the exponent
return int(sf), -int(len(sf)-1-exp)

最新更新