How to reliably separate decimal and floating parts from a number?
这不是这个的副本,我在这里解释。
以
1 2 3 4 5 6 7 8 9 10 11 12 13 | In [370]: x = 1.2 In [371]: divmod(x, 1) Out[371]: (1.0, 0.19999999999999996) In [372]: math.modf(x) Out[372]: (0.19999999999999996, 1.0) In [373]: x - int(x) Out[373]: 0.19999999999999996 In [374]: x - int(str(x).split('.')[0]) Out[374]: 0.19999999999999996 |
我所做的一切都没有给我确切的答案。
是否有任何方法可以可靠地将浮点数转换为十进制和浮点数等价物,而不受浮点数表示的限制?
我理解这可能是由于数字本身存储方式的限制,所以我愿意接受任何可以克服这一点的建议(如包装或其他)。
编辑:如果可能的话,最好使用不涉及字符串操作的方法。
解决方案
它看起来像一个黑客,但你可以分离字符串形式(实际RPR),并将其转换为int和浮动:
1 2 3 4 5 6 7 8 9 10 11 | In [1]: x = 1.2 In [2]: s = repr(x) In [3]: p, q = s.split('.') In [4]: int(p) Out[4]: 1 In [5]: float('.' + q) Out[5]: 0.2 |
它是如何工作的
这样接近的原因是显示
在内部,输入为
1 2 3 4 5 6 7 | In [6]: from decimal import Decimal In [7]: Decimal(1.2) Out[7]: Decimal('1.1999999999999999555910790149937383830547332763671875') In [8]: (1.2).as_integer_ratio() Out[8]: (5404319552844595, 4503599627370496) |
基本原理和问题分析
如前所述,您的问题大致翻译为"我希望根据数字的实际存储方式,将数字的整数部分和小数部分进行拆分,因为它在视觉上看起来更像是这样"。
以这种方式构建,很明显,解决方案涉及解析它的可视化显示方式。虽然这让人感觉像是一次黑客攻击,但这是利用非常复杂的显示算法并与您所看到的内容相匹配的最直接的方法。
除非您手动复制内部显示算法,否则这种方法可能是匹配您所看到内容的唯一可靠方法。
备选方案失效如果您想保持整数的状态,您可以尝试舍入和减法,但这会为浮点部分提供一个意外的值:
1 2 3 4 5 | In [9]: round(x) Out[9]: 1.0 In [10]: x - round(x) Out[10]: 0.19999999999999996 |
这里有一个不需要字符串操作的解决方案(
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | >>> def integer_and_fraction(x, frac_digits=3): ... i = int(x) ... c = 10**frac_digits ... f = round(x*c-i*c)/c ... return (i, f) ... >>> integer_and_fraction(1.2) (1, 0.2) >>> integer_and_fraction(1.2, 1) (1, 0.2) >>> integer_and_fraction(1.2, 2) (1, 0.2) >>> integer_and_fraction(1.2, 5) (1, 0.2) >>> |
所以我在一个python终端上做了以下的工作,它看起来工作正常…
1 2 3 4 | x=1.2 s=str(x).split('.') i=int(s[0]) d=int(s[1])/10 |
您可以尝试将1.2转换为字符串,在"."上拆分,然后将两个字符串("1"和"2")转换回所需的格式。
另外,用"0"填充第二部分。这将为您提供一个很好的格式。