在没有字符串的情况下将浮点数分解为基数10中的尾数和指数

jpm*_*jpm 12 python

Python库或numpy中是否有函数将float作为输入并返回其十进制科学符号分解,即尾数和指数?或者是否有一种简单的方法来实现这一点,而无需借助字符串转换或使用for循环来确定指数?编写这样的函数并不困难,我很震惊,我在查找数学,十进制或numpy中的现有函数时遇到了麻烦.

例如,如果fexpfman是给出float的十进制浮点表示的指数和尾数的函数,那么我们期望以下语句都返回true:

fexp(154.3) == 2.0
fman(154.3) == 1.543
fexp(-1000) == 3.0
fman(-1000) == -1.0
Run Code Online (Sandbox Code Playgroud)

简而言之,这将是"十进制版本" math.frexp.

jsa*_*nen 14

避免字符串转换的一种方法是使用Decimals实现方法:

from decimal import Decimal

def fexp(number):
    (sign, digits, exponent) = Decimal(number).as_tuple()
    return len(digits) + exponent - 1

def fman(number):
    return Decimal(number).scaleb(-fexp(number)).normalize()
Run Code Online (Sandbox Code Playgroud)

请注意,使用浮点数,不能计算尾数和指数而不进行舍入.原因是浮点数存储为基数2分数.例如,154.3is的存储浮点值154.30000000000001136868377216160297393798828125.浮点数在控制台中显示为准确的数字,因为(在CPython中)它们在使用硬编码精度17进行序列化时始终为圆角.

  • @jsalonen我建议删除有关舍入的注释.在您的示例中,154.3以粗略的方式存储在内存中,仅为154.30000000000001136868377216160297393798828125.Base-2浮点数不能完全保留Base-10,但对于存储Base-2的Base-10 FP数字则不然.原因是简单的算术.每个2 ^ -N可以精确地表示在Base-10(0.5,0.25,0.125等)中,最终结果只是它们的总和.否则很好的答案.由于问题是关于分解浮点数,关于编写浮点数的声明可能会导致误解. (2认同)

jpm*_*jpm 8

我希望有一个更好的答案,但我想出了

from math import floor, log10

def fexp(f):
    return int(floor(log10(abs(f)))) if f != 0 else 0

def fman(f):
    return f/10**fexp(f)
Run Code Online (Sandbox Code Playgroud)

  • @jpm 也是为了获得与``math.frexp(0)`` 相同的行为。 (2认同)