[英]Decompose a float into mantissa and exponent in base 10 without strings
Python 库或numpy 库中是否有将浮点数作为输入并返回其十进制科学计数法分解(即尾数和指数)的函数? 或者是否有一种 BRIEF 方法可以在不求助于字符串转换或使用 for 循环来确定指数的情况下完成此操作? 写这样一个 function 并不难,我只是很震惊,我在数学、十进制或 numpy 中找不到现有的一个。
例如,如果fexp
和fman
是给出 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.