如何使用 SI 前缀(micro、milli、Mega、Giga 等)格式化数字?

fea*_*ool 6 python string-formatting

我的数字范围从非常小到非常大,我想使用带有大小和后缀的“工程符号”来格式化它们:

n.nnn S
Run Code Online (Sandbox Code Playgroud)

其中 1.0 <= n.nnn < 1000.,S 是公制 (SI) 前缀。所以:

1234.5e+13 => 12.35P
12345678 => 12.35M
1234 => 1.234K
1.234 => 1.234
0.1234 => 123.4m
1234.5e-16 => 1.235f
Run Code Online (Sandbox Code Playgroud)

等等。我该如何做到这一点,例如使用Python?

fea*_*ool 5

(以问答形式发布在这里,因为我不断重新发明这段代码,其他人可能会发现它很有帮助。如果您看到改进,请随意调整它......)

\n

这是一种实现,可以让您选择长后缀(例如“peta”)或短后缀(例如“P”),还可以让您选择显示的总位数(即精度):

\n
def si_classifier(val):\n    suffixes = {\n        24:{'long_suffix':'yotta', 'short_suffix':'Y', 'scalar':10**24},\n        21:{'long_suffix':'zetta', 'short_suffix':'Z', 'scalar':10**21},\n        18:{'long_suffix':'exa', 'short_suffix':'E', 'scalar':10**18},\n        15:{'long_suffix':'peta', 'short_suffix':'P', 'scalar':10**15},\n        12:{'long_suffix':'tera', 'short_suffix':'T', 'scalar':10**12},\n        9:{'long_suffix':'giga', 'short_suffix':'G', 'scalar':10**9},\n        6:{'long_suffix':'mega', 'short_suffix':'M', 'scalar':10**6},\n        3:{'long_suffix':'kilo', 'short_suffix':'k', 'scalar':10**3},\n        0:{'long_suffix':'', 'short_suffix':'', 'scalar':10**0},\n        -3:{'long_suffix':'milli', 'short_suffix':'m', 'scalar':10**-3},\n        -6:{'long_suffix':'micro', 'short_suffix':'\xc2\xb5', 'scalar':10**-6},\n        -9:{'long_suffix':'nano', 'short_suffix':'n', 'scalar':10**-9},\n        -12:{'long_suffix':'pico', 'short_suffix':'p', 'scalar':10**-12},\n        -15:{'long_suffix':'femto', 'short_suffix':'f', 'scalar':10**-15},\n        -18:{'long_suffix':'atto', 'short_suffix':'a', 'scalar':10**-18},\n        -21:{'long_suffix':'zepto', 'short_suffix':'z', 'scalar':10**-21},\n        -24:{'long_suffix':'yocto', 'short_suffix':'y', 'scalar':10**-24}\n    }\n    exponent = int(math.floor(math.log10(abs(val))/3.0)*3)\n    return suffixes.get(exponent, None)\n\ndef si_formatter(value):\n    '''\n    Return a triple of scaled value, short suffix, long suffix, or None if\n    the value cannot be classified.\n    '''\n    classifier = si_classifier(value)\n    if classifier == None:\n        # Don't know how to classify this value\n        return None\n\n    scaled = value / classifier['scalar']\n    return (scaled, classifier['short_suffix'], classifier['long_suffix'])\n\ndef si_format(value, precision=4, long_form=False, separator=''):\n    '''\n    "SI prefix" formatted string: return a string with the given precision\n    and an appropriate order-of-3-magnitudes suffix, e.g.:\n        si_format(1001.0) => '1.00K'\n        si_format(0.00000000123, long_form=True, separator=' ') => '1.230 nano'\n    '''\n    scaled, short_suffix, long_suffix = si_formatter(value)\n\n    if scaled == None:\n        # Don't know how to format this value\n        return value\n\n    suffix = long_suffix if long_form else short_suffix\n\n    if abs(scaled) < 10:\n        precision = precision - 1\n    elif abs(scaled) < 100:\n        precision = precision - 2\n    else:\n        precision = precision - 3\n\n    return '{scaled:.{precision}f}{separator}{suffix}'.format(\n        scaled=scaled, precision=precision, separator=separator, suffix=suffix)\n
Run Code Online (Sandbox Code Playgroud)\n