查找小数位的简便方法

问题描述

| 有没有简单的方法或集成函数来找出浮点数的小数位? 该数字是从字符串中解析出来的,所以一种方法是对\'。\'符号后面的数字进行计数,但是对我来说这看起来很笨拙。是否有可能从“ 0”或“ 1”对象中获取所需的信息? 解决方案(当然是其中之一:)) 我选择使用python decimal.Decimal类来帮助解决我的问题:
e = abs(Decimal(string_value).as_tuple().exponent)
注意:仅当从其构造Decimal的参数是字符串而不是浮点数时(这会导致浮点错误),此方法才有效。 非常感谢您所做的所有其他贡献。     

解决方法

        重复别人说的话(因为我已经输入了!),由于十进制和二进制表示形式之间的差异,我什至不确定在浮点数的情况下该值是否有意义。通常,用有限数量的十进制数字表示的数字将只有二进制形式的无限数字表示。 对于
decimal.Decimal
对象,可以使用
as_tuple
方法检索指数,该方法返回具有
sign
digits
exponent
属性的命名元组:
>>> d = decimal.Decimal(\'56.4325\')
>>> d.as_tuple().exponent
-4
>>> d = decimal.Decimal(\'56.43256436\')
>>> d.as_tuple().exponent
-8
指数的取反是小数点后的位数,除非指数大于
0
。     ,        天真的方法(容易受到@jglouie提到的本地化用法的影响)是
len(foo.split(\'.\')[1])
其中foo是一个类似\“ 23.512999238 \”的字符串。 编辑 正如@Thomas Jung和@Mark Ransom提到的那样,对于某些极端情况而言,这是很幼稚的,需要将其作为...
import re
from locale import localeconv
dec_pt = localeconv()[\'decimal_point\']
decrgx = re.compile(\"\\d+(%s\\d+)?e(-|\\+)(\\d+)\" % dec_pt)
if decrgx.search(foo):
    # still figuring this out
    raise NotImplementedError,\"e notation not implemented\"
else:
    digits = len(foo.split(dec_pt)[-1])
    ,        “小数位数”不是浮点数具有的属性,因为它们在内部存储和处理的方式。 您可以从浮点数获得尽可能多的小数位。问题是您想要多少精度。将浮点数转换为字符串时,部分过程将取决于精度。 例如尝试:
1.1 - int(1.1)
您将看到答案是:
0.10000000000000009
因此,在这种情况下,小数位数为17。这可能不是您要查找的数字。 但是,您可以使用\“ round \”将数字四舍五入到小数位数:
round(3.1415 - int(3.1415),3)
在这种情况下,小数位数将减少为3。 您无法获得“浮点数的小数位数”,但可以确定精度以及所需的位数。 将浮点数转换为字符串是做出此类决定的一种方法。     ,        十进制库用于处理十进制数字,例如在Accounting中。它本身不具有返回小数位数的功能。当您意识到运行的上下文将其设置为用户所需的任何值时,这尤其是一个问题。 如果您得到一个字符串,则可以转换为十进制,但这可以用零点表示以确保准确性,也可以使用舍入设置截断它。 最好的选择可能是对字符串中的点进行拆分,然后计算结果子字符串中的字符数。     ,        我需要这样的东西,我测试了其中一些,发现最快的是:
str(number)[::-1].find(\'.\')
由于存在浮点问题,即使使用Decimal(number),所有模数都给了我错误的结果(请注意,我需要在脚本中使用它来确定整个数据库的价格)
len(str(Decimal(str(number))) % Decimal(1))) - 2
当我们有浮点数或类似的东西时,将字符串放入Decimal的需求非常不容易。 这是我的“长凳”: https://repl.it/FM8m/17     ,        如果您知道自己不会遇到解析问题(或者如果让python本身或其他库为您处理该问题,希望可以处理本地化问题)...只需对其进行解析并使用modf。返回值是一对值,其中一个是整数部分,另一个是小数部分。     ,        由于Python浮点数在内部表示为二进制而不是十进制,因此除了转换为十进制外,实际上没有其他捷径。唯一的内置方法是转换为字符串。您可以编写自己的代码以进行十进制转换并计算位数,但这是重复的工作。     ,        我找到小数点后的计算位数并四舍五入的最快方法是 计算数字:
a=decimal.Decimal(\'56.9554362669143476\');
lenstr = len(str(a).split(\".\")[1])
计算,检查和舍入:
a=decimal.Decimal(\'56.9554362669143476\');
a = round(float(a),5) if len(str(a).split(\".\")[1]) > 5 else float(a)
比较:
$ python2 -mtimeit \'import decimal; a=decimal.Decimal(\'56.9554362669143476\'); round(float(a),5) if a.as_tuple().exponent < -5 else float(a)\'
10000 loops,best of 3: 32.4 usec per loop
$ python -mtimeit \'import decimal; a=decimal.Decimal(\'56.9554362669143476\'); a = round(float(a),5) if len(str(a).split(\".\")[1]) > 5 else float(a)\'
100000 loops,best of 3: 16.7 usec per loop
    ,如果只需要找到最高有效数字的小数位,即。最左边的另一个原始解决方案是:
fraction = 0.001
decimal_places = int(f\'{fraction:e}\'.split(\'e\')[-1])
这利用了科学记数法(m x 10 ^ n),该科学记数法已经以10的幂(n)的形式提供了小数位数,系数(m)增大到该位数。 -3,来自上述示例的1.000000e-03。 与ѭ21的一个重要区别是,科学记数法将始终仅考虑指数n的最高有效位数,类似于
Decimal().adjusted()
,而
Decimal().as_tuple().exponent
则返回最低有效位数的指数。 将字符串格式化为科学计数法当然也只能处理浮点数,而不能处理任何字符串,因此任何浮点算术问题都会持续存在。但是,对于许多用例,以上可能就足够了。