在Python中将浮点数转换为带有工程符号(SI前缀)的字符串

在Python中将浮点数转换为带有工程符号(SI前缀)的字符串,python,string,numbers,Python,String,Numbers,我有一个浮点数,比如x=23392342.1 我想把它转换成一个带工程符号的字符串(带公制前缀) 在我的例子中,23392342.1=23.3923421E6=23.3923421米(兆) 我想显示23.3923421 M一个直接的解决方案是使用该方法,然后进行字典查找,将指数转换为适当的度量前缀。以下是一个受 metric.py #!/usr/bin/env python # -*- coding: utf-8 -*- import math def to_si(d, sep=' '

我有一个浮点数,比如
x=23392342.1

我想把它转换成一个带工程符号的字符串(带公制前缀)

在我的例子中,23392342.1=23.3923421E6=23.3923421米(兆)


我想显示
23.3923421 M

一个直接的解决方案是使用该方法,然后进行字典查找,将指数转换为适当的度量前缀。

以下是一个受

metric.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import math


def to_si(d, sep=' '):
    """
    Convert number to string with SI prefix

    :Example:

    >>> to_si(2500.0)
    '2.5 k'

    >>> to_si(2.3E6)
    '2.3 M'

    >>> to_si(2.3E-6)
    '2.3 µ'

    >>> to_si(-2500.0)
    '-2.5 k'

    >>> to_si(0)
    '0'

    """

    inc_prefixes = ['k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']
    dec_prefixes = ['m', 'µ', 'n', 'p', 'f', 'a', 'z', 'y']

    if d == 0:
        return str(0)

    degree = int(math.floor(math.log10(math.fabs(d)) / 3))

    prefix = ''

    if degree != 0:
        ds = degree / math.fabs(degree)
        if ds == 1:
            if degree - 1 < len(inc_prefixes):
                prefix = inc_prefixes[degree - 1]
            else:
                prefix = inc_prefixes[-1]
                degree = len(inc_prefixes)

        elif ds == -1:
            if -degree - 1 < len(dec_prefixes):
                prefix = dec_prefixes[-degree - 1]
            else:
                prefix = dec_prefixes[-1]
                degree = -len(dec_prefixes)

        scaled = float(d * math.pow(1000, -degree))

        s = "{scaled}{sep}{prefix}".format(scaled=scaled,
                                           sep=sep,
                                           prefix=prefix)

    else:
        s = "{d}".format(d=d)

    return s


if __name__ == "__main__":
    import doctest
    doctest.testmod()
它将显示

23.3923421 M
使用软件包。它是一个稳定的、有良好文档记录和良好支持的软件包,旨在实现您想要的功能

>>> from quantiphy import Quantity

>>> v = Quantity(23.3923421E6)                                               
>>> str(v)                                                                   
'23.392M'                                                                    

>>> v.render(prec='full')                                                    
'23.3923421M'
通常人们使用国际单位制前缀和单位,而数量设计为单位与数字的组合

>>> v = Quantity(23.3923421E6, 'V')
>>> print(v)
23.392 MV

>>> f = Quantity('23.3923421 MHz')
>>> print('{}'.format(f))
23.392 MHz
Quantity子类为float,因此可以像使用float一样在表达式中使用数量:

>>> t = 1/f                                                                  
>>> print(t)                                                                 
4.274903281275114e-08

>>> t = Quantity(t, 's')                                                     
>>> print(t)
42.749 ns
您可以使用带有附加格式选项的浮点类型

来自带前缀的导入浮点的
>>
>>>x=浮动(23392342.1)
>>>打印(f'{x:!h}')
23.392342米
或者如果你想保留小数点后7位

>>> print(f'{x:!.7h}')
23.3923421 M


这是一个没有依赖关系的简单方法:

def to_units(x_):
    units = {-12: "T",-9: "G",-6: "M",-3: "K",0: "",3: "m",6: "µ",9: "n",12: "p",15: "f"}
    k = -12
    while x_ * 10.0**k < 1: 
        k += 3
    return f"{x_*10.0**k}{units[k]}"

请告诉我们您将如何处理您的问题,以及为什么您认为您的想法不是最佳的,或者您的想法的哪一部分无法实现。我想我需要一个dict来存储每个度量前缀。我可能会计算log10来找到“最近的”指数,它是3的倍数(但除了da,h,)。。。但这并不是那么微不足道。。。(由于这种例外情况)。。。我还想知道Python是否没有标准的方法来完成这样的任务,因为我想管理所有可能的度量前缀。那么,如何获得指数值呢?您必须解析字符串!!有两个相关的问题可以被认为是重复的,应该(自动)链接。第一个使用您的解决方案()。副本还显示了一种方法:参数需要测试零,因为未定义,导致
ValueError:math domain error
。例如:````如果d==0.0:degree=0,否则:degree=int(…````我将其转储到扩展的
int
类的
\uu str\uuu
方法中,以便可以在字符串格式输出中使用。例如:
导入度量;打印('>%s'%metric.MetricInt(2**16));
非常喜欢您的函数!有关缺少的NaN支持,请参阅
def to_units(x_):
    units = {-12: "T",-9: "G",-6: "M",-3: "K",0: "",3: "m",6: "µ",9: "n",12: "p",15: "f"}
    k = -12
    while x_ * 10.0**k < 1: 
        k += 3
    return f"{x_*10.0**k}{units[k]}"
for i in range(-15,15):
    print(f"{to_units(1*10.0**i)} \t {1*10.0**i:1,.15f}")

1.0f    0.000000000000001
10.0f   0.000000000000010
100.0f  0.000000000000100
1.0p    0.000000000001000
10.0p   0.000000000010000
100.0p  0.000000000100000
1.0n    0.000000001000000
10.0n   0.000000010000000
100.0n  0.000000100000000
1.0µ    0.000001000000000
10.0µ   0.000010000000000
100.0µ  0.000100000000000
1.0m    0.001000000000000
10.0m   0.010000000000000
100.0m  0.100000000000000
1.0     1.000000000000000
10.0    10.000000000000000
100.0   100.000000000000000
1.0K    1,000.000000000000000
10.0K   10,000.000000000000000
100.0K  100,000.000000000000000
1.0M    1,000,000.000000000000000
10.0M   10,000,000.000000000000000
100.0M  100,000,000.000000000000000
1.0G    1,000,000,000.000000000000000
10.0G   10,000,000,000.000000000000000
100.0G  100,000,000,000.000000000000000
1.0T    1,000,000,000,000.000000000000000
10.0T   10,000,000,000,000.000000000000000
100.0T  100,000,000,000,000.000000000000000