【问题标题】:NEON int32 conversion to float gives wrong resultNEON int32 转换为浮点数会产生错误的结果
【发布时间】:2018-05-26 02:44:54
【问题描述】:

在 NEON 内联汇编中,从 Signed int32 转换为 Float 后,数字不同。

这里打印了 Float 和 Signed int32 的输出:

它随机不同(不仅是每个偶数)。 save as sint32 和 as float 之间只有转换(没有任何其他操作)。

如何避免?谢谢

【问题讨论】:

    标签: floating-point type-conversion arm inline-assembly neon


    【解决方案1】:

    浮点数只有 23 位分配给尾数,带有单独的符号位 (MSB)

    因此,在 -2^24 ~ 2^24-1 窗口之外的任何 int32 都将在转换过程中失去精度。 (发生截断)

    与 ARM/NEON 无关。

    https://en.wikipedia.org/wiki/Single-precision_floating-point_format

    【讨论】:

    • 有效数字(首选术语;有效数字是线性的,而尾数在历史上是对数)有 24 位。尽管仅显式存储了 23 位,但第 24 位是从有效数和指数的组合中推断出来的。这使得可表示整数的范围从 -2**24 到 +2**24,而不是 2**23。
    • @EricPostpischil 你是对的!我会相应地修改我的答案。
    • 该范围之外的一些整数完全可表示的。具体来说,具有足够尾随零的整数。即在基数 2 中只有 24 个或更少的有效数字。因此,超出该范围的 any int32 失去精度并不完全正确;例如可以精确表示 2 的任何幂(低于 FLT_MAX),包括超出int32_t 可以容纳的范围的值。所有超出 24 位范围的 float 值都是整数。
    • 而且它们可能不会被截断为零; ARM intfloat 转换不使用默认舍入模式(舍入到最接近的偶数)吗?
    • @PeterCordes 这取决于配置。而且我一直在研究固定数字,尽可能避免使用浮点类型。
    【解决方案2】:

    单精度浮点数的有效位(小数部分)只有 24 位。 (显式存储 23 位;从指数和有效数组合推断出 1。)因此值大于 224 的整数必须四舍五入以适应浮点格式。

    【讨论】:

      【解决方案3】:

      解决了使用 NEON 指令转换为 64 位 int 再转换为 64 位浮点数的问题。

      【讨论】:

      • NEON 不是直接从压缩的 32 位 int 转换为压缩的 64 位 double 精度浮点数吗? x86 SSE2 可以。
      • NEON 根本不支持双精度。但是 AArch64 Advanced SIMD 可以,这就是您正在使用的 (scvtf)。看起来它目前不支持打包的 32 位 int -> double,只支持标量(如 ARM32 VFP)。所以是的,与使用带有 sshll 指令的标量相比,首先转换为 64 位 int 可能是一个不错的选择。 (shll2 表示 16 字节向量的上半部分)。
      • 我认为你使用的实际上是一个VFP指令。
      猜你喜欢
      • 2022-06-14
      • 2011-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多