Python以可能的最小步长递增float,该步长由其小数位数预先确定

c3frrgcw  于 2023-03-28  发布在  Python
关注(0)|答案(3)|浏览(206)

我已经找了几个小时了,我找不到一个简单的方法来完成下面的工作。

Value 1 = 0.00531
Value 2 = 0.051959
Value 3 = 0.0067123

我想增加每个值的最小小数点(然而,数字必须保持小数点的确切数量,因为它开始时,小数点的数量随每个值而变化,因此我的麻烦)。

Value 1 should be: 0.00532
Value 2 should be: 0.051960
Value 3 should be: 0.0067124

有没有人知道一个简单的方法来完成上述功能,仍然可以处理任何数量的小数?
谢谢。

vngu2lb8

vngu2lb81#

你看过标准模块decimal吗?
它规避了浮点行为。
只是为了说明可以做些什么。

import decimal
my_number = '0.00531'
mnd = decimal.Decimal(my_number)
print(mnd)
mnt = mnd.as_tuple()
print(mnt)
mnt_digit_new = mnt.digits[:-1] + (mnt.digits[-1]+1,)
dec_incr = decimal.DecimalTuple(mnt.sign, mnt_digit_new, mnt.exponent)
print(dec_incr)
incremented = decimal.Decimal(dec_incr)
print(incremented)

印刷品

0.00531
DecimalTuple(sign=0, digits=(5, 3, 1), exponent=-5)
DecimalTuple(sign=0, digits=(5, 3, 2), exponent=-5)
0.00532

或完整版本(编辑后也携带任何数字,所以它也适用于'0.199')...

from decimal import Decimal, getcontext

def add_one_at_last_digit(input_string):
    dec = Decimal(input_string)
    getcontext().prec = len(dec.as_tuple().digits)
    return dec.next_plus()

for i in ('0.00531', '0.051959', '0.0067123', '1', '0.05199'):
    print(add_one_at_last_digit(i))

打印机

0.00532
0.051960
0.0067124
2
0.05200
pw9qyyiw

pw9qyyiw2#

正如其他评论者所指出的:你不应该用floats操作,因为一个给定的数字0.1234被转换成一个内部表示,你不能进一步处理它的方式,你想要的。这是故意模糊的公式化。浮点本身就是一个主题。This article很好地解释了这个主题,是一个很好的入门。
也就是说,你可以做的是将输入作为字符串(例如,从输入阅读时不要将其转换为浮点数)。然后你可以这样做:

from decimal import Decimal

def add_one(v):
    after_comma = Decimal(v).as_tuple()[-1]*-1
    add = Decimal(1) / Decimal(10**after_comma)
    return Decimal(v) + add

if __name__ == '__main__':
    print(add_one("0.00531"))
    print(add_one("0.051959"))
    print(add_one("0.0067123"))
    print(add_one("1"))

这个打印

0.00532
0.051960
0.0067124
2

更新

如果你 * 需要 * 对浮点数进行操作,你可以 * 尝试 * 使用模糊逻辑来结束演示。decimal提供了一个normalize函数,可以让你降低十进制表示的精度,以便它与原始数字匹配:

from decimal import Decimal, Context

def add_one_float(v):
    v_normalized = Decimal(v).normalize(Context(prec=16))
    after_comma = v_normalized.as_tuple()[-1]*-1
    add = Decimal(1) / Decimal(10**after_comma)
    return Decimal(v_normalized) + add

但请注意,16的精度是纯实验性的,你需要尝试一下,看看它是否能产生你想要的结果。如果你需要正确的结果,你不能走这条路。

a11xaf1n

a11xaf1n3#

使用数字作为输入并实现减法的一点改进:

import decimal 

def add_or_sub_one_at_last_digit(input_number,to_add = True):
    dec = decimal.Decimal(str(input_number))
    decimal.getcontext().prec = len(dec.as_tuple().digits)
    ret = dec.next_plus() if to_add else dec.next_minus()
    return ret 

a = 0.225487
# add
print(add_or_sub_one_at_last_digit(a))
# substract
print(add_or_sub_one_at_last_digit(a,False))

输出:

0.225488
0.225486

相关问题