繁体   English   中英

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

[英]Decompose a float into mantissa and exponent in base 10 without strings

Python 库或numpy 库中是否有将浮点数作为输入并返回其十进制科学计数法分解(即尾数和指数)的函数? 或者是否有一种 BRIEF 方法可以在不求助于字符串转换或使用 for 循环来确定指数的情况下完成此操作? 写这样一个 function 并不难,我只是很震惊,我在数学、十进制或 numpy 中找不到现有的一个。

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

fexp(154.3) == 2.0
fman(154.3) == 1.543
fexp(-1000) == 3.0
fman(-1000) == -1.0

简而言之,这将是math.frexp的“十进制版本”。

避免字符串转换的一种方法是使用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()

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

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

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)

ChatGPT 给了我一些关于这种方式的线索......

我认为它非常优雅,但似乎在 1e-324 附近中断

import math
def man(value:float, significant_digits:int=4):
    return float(f"{value:.{significant_digits}e}".split('e')[0]) if math.isfinite(value) else float('nan')
def exp(value:float, significant_digits:int=4):
    return int(f"{value:.{significant_digits}e}".split('e')[1]) if math.isfinite(value) else float('nan')
def man_exp(value:float, significant_digits:int=4):
    return man(value, significant_digits), exp(value, significant_digits)

print(man_exp(.000006748439390))
print(man_exp(-3456.67858543, 5))
print(man_exp(.000006748439390,100))
print(man_exp(float('nan')))
print(man_exp(float('inf')))
print(man_exp(float('-inf')))
print(man_exp(0))
print(man_exp(0,6))
print(man_exp(1.25e-12,6))
print(man_exp(1.25e-308,6))
print(man_exp(1.25e-323,6))
print(man_exp(1.25e-324,6))
print(math.isfinite(1.25e-324))
(6.7484, -6)
(-3.45668, 3)
(6.74843939, -6)
(nan, nan)
(nan, nan)
(nan, nan)
(0.0, 0)
(0.0, 0)
(1.25, -12)
(1.25, -308)
(1.482197, -323)
(0.0, 0)
True

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM