【问题标题】:How to convert a number to 12 bits precision in python?如何在python中将数字转换为12位精度?
【发布时间】:2017-11-30 12:39:00
【问题描述】:

我需要在 Python 中存储一个 12 位精度的浮点变量

我知道要在 float 中转换变量,有一个 float 函数,但我如何指定 float 的大小(以位为单位)?例如(12, 16, ...)

【问题讨论】:

  • 这是一种相当不寻常的浮点格式。它的规格是什么?你确定它不是 80 位,或者可能是 80 位填充到 128 位?见en.wikipedia.org/wiki/…
  • @PM2Ring 这是因为我正在研究一个在 float 12 中工作的嵌入式卡,我想模拟分析数据。简单的方法是在我的 python 代码中直接生成 12 字节的数据。
  • 我认为这是一个合理的问题,与关闭/否决票相反,尽管表面上看起来很奇怪。我最初也很想投票接近,但在意识到 OP 的背景是强大的数学/物理学之后更仔细地检查。作为对未来 Qs 的建议,也许可以像上面一样放一些相关的简介/强调自己的研究工作,以便读者意识到它有点复杂。
  • 好的,但正如我所说,这是一种不寻常的格式。更令人惊讶的是嵌入式系统会使用如此高精度的浮点数。在 Python 中使用它并不容易,但你需要有它的确切规范。
  • 即使您只想创建随机数据并且不需要对这些数字进行任何实际算术运算,您仍然需要数据规范,这样您就不会创建无效的位模式。

标签: python types floating-point precision floating-accuracy


【解决方案1】:

正如其他答案中提到的,这并不存在 在纯 python 数据类型中,see the docs

但是,您可以使用 numpy 来指定明确的 data types,例如

  • numpy.float16
  • numpy.float32
  • numpy.float64

您也可以使用numpy.float96 中的extended precision,这似乎是您所追求的,例如 12 字节是 96 位

import numpy as np
high_prec_array = np.array([1,2,3], dtype=np.float96)

注意事项

正如 cmets 和链接中所指出的,这不是真正的 12 字节精度。而是用 2 个零字节填充 80 位(10 字节)。如果您只关心兼容性,这可能就足够了。

这个精度may not be available on all platforms

在下表中,平台?表示该类型可能不是 可在所有平台上使用。与不同的 C 或 Python 的兼容性 指示类型:如果两种类型的数据属于 大小相同,解释方式相同。

另请阅读这篇关于使用这种奇异类型的注意事项

我发现这很有启发性。我的结论是,如果您想绝对保证96bit 精度,那么python 不是正确的选择,因为可用扩展精度的固有歧义来自C 发行版中的歧义。鉴于您的物理背景,如果您想保证稳定性,我建议您使用Fortran

在 C++ 中定义自己的类型

对于感兴趣的高级用户,可以定义自己的数据类型。 numpyuser defined types states 上的指南

作为我认为有用的能力应用的一个例子 添加数据类型是添加数据类型的可能性 任意精度浮动到 NumPy。

因此,如果您非常希望将代码保存在 python 中,可以尝试使用 boost/multiprecision/cpp_bin_float.hpp

【讨论】:

  • NumPy 不支持 12 字节浮点类型。在某些平台上,它有一个名为 float96 的类型,但这是 80 位(10 字节)IEEE 754-1985 64 位精度扩展格式(1 个符号位,15 个指数位,64 个有效位,无隐藏位)由 Intel x87 使用,并用两个零字节填充最多 12 个字节。我知道这些信息隐含在您的链接中,但我认为这个答案具有误导性。
  • 是的,我还在研究它 - 因此信息有些矛盾。这似乎是一个相当复杂的问题!我认为 OP 只需要将格式设置为 12 字节以实现兼容性,因此即使最后两个字节被两个零字节填充它也不重要
  • cmets(尤其是 StarBucK 的最后一个)似乎表明他毕竟需要 12 个 BITS。他只是提到了几次字节,因为他不知道位和字节的区别。我认为任何语言中 12 位浮点数的实现都不多。
【解决方案2】:

python 中的 float 类型是固定的。通常是 64 位,但它依赖于实现。

你可以使用sys.float_info知道浮动的大小,但你不应该能够改变它。

https://docs.python.org/3/library/sys.html#sys.float_info

编辑:

如果确实需要指定float大小,可以依赖外部库,比如numpy。请参阅内容丰富的answer of Alexander McFarlane 了解更多详情

【讨论】:

  • “浮点类型 ... 是固定的。通常为 64 位,但可以更改”不清楚。它是固定的还是依赖于实现的?
  • 它依赖于实现。在特定的实现中,它不会改变。但一种实现可能是 64 位,另一种是 32 位。 (编辑我的答案,感谢反馈)
  • @chux:至少对于 CPython,它已经有效地修复了,因为 Python floats 使用 C doubles,并且假设 sizeof(double) == 8 被纳入 CPython 源代码。 (这很糟糕,但迄今为止似乎并没有造成任何真正的问题。)IronPython 和 Jython 存在于明确指出 Double 是 IEEE 754 binary64 的平台(.NET 和 Java)上。 MicroPython 可能会做一些有趣的事情,但我不知道。
【解决方案3】:

gmpy2的开发版支持96位IEEE数字类型。

>>> import gmpy2
>>> gmpy2.version()
'2.1.0a1'
>>> gmpy2.set_context(gmpy2.ieee(96))
>>> gmpy2.get_context()
context(precision=83, real_prec=Default, imag_prec=Default,
        round=RoundToNearest, real_round=Default, imag_round=Default,
        emax=4096, emin=-4175,
        subnormalize=True,
        trap_underflow=False, underflow=False,
        trap_overflow=False, overflow=False,
        trap_inexact=False, inexact=False,
        trap_invalid=False, invalid=False,
        trap_erange=False, erange=False,
        trap_divzero=False, divzero=False,
        allow_complex=False,
        rational_division=False)
>>> gmpy2.mpfr(1)/7
mpfr('0.14285714285714285714285714',83)
>>> 

在旧版本的gmpy2 中也可以使用,但需要更多的努力。

>>> import gmpy2
>>> gmpy2.version()
'2.0.8'
>>> ieee96 = gmpy2.context(precision=83, emax=4096, emin=-4175, subnormalize=True)
>>> gmpy2.set_context(ieee96)
>>> gmpy2.mpfr(1)/7
mpfr('0.14285714285714285714285714',83)
>>> 

您可能需要直接从https://github.com/aleaxit/gmpy下载源代码。 https://pypi.python.org/pypi/gmpy2/2.1.0a1 提供一些非常早期的轮子。

免责声明:我维护gmpy2

【讨论】:

    猜你喜欢
    • 2010-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-27
    • 2019-05-20
    • 1970-01-01
    • 2010-09-24
    • 1970-01-01
    相关资源
    最近更新 更多