【问题标题】:Negative fixed point number representation负定点数表示
【发布时间】:2020-03-31 02:19:47
【问题描述】:

我正在编写一个通用例程,用于在十进制和二进制表示之间转换定点数。

对于正数,处理很简单,但是当事情涉及到负数时,我发现了不同的来源。 Someone 说有一个用于保存符号的位,而others 说整数应该使用 2 的补码表示为伪整数,即使它是负数。

请任何人告诉我哪个来源是正确的,或者有符号定点数是否有标准表示?

此外,如果 2 的补码表示是正确的,那么如何用零整数部分表示负数。例如-0.125?

【问题讨论】:

    标签: binary bit-shift twos-complement negative-number fixed-point


    【解决方案1】:

    定点数只是位值已更改的二进制值。为位分配位置值是一种任意的人类活动,我们可以以任何有意义的方式进行。通常我们谈论二进制整数,因此将位置值 2^0 = 1 分配给 LSB,将 2^1=2 分配给 LSB 左侧的位,以此类推会很方便。对于 N 位整数,MSB 的位值变为 2^(N-1)。如果我们想要二进制补码表示,我们将 MSB 的位值更改为 -2^(N-1),并且所有其他位的位值都保持不变。

    对于定点值,如果我们想让 F 位表示数字的小数部分,那么 LSB 的位值变为 2^(0-F) 并且 MSB 的位值对于无符号数变为 2^(N-1-F),对于有符号数变为 -2^(N-1-F)。

    那么,我们如何在二进制补码定点值中表示 -0.125?这等于 0.875 - 1,因此我们可以使用 MSB 的位值为 -1 并且所有其他位的值加起来为 0.875 的表示。如果您选择一个 4 位定点数,带有 3 个小数位,您会说 1111 二进制等于 -0.125 十进制。将我们拥有的位的位置值相加 (-1) + 0.5 + 0.25 + 0.125 = -0.125。我个人的偏好是将二进制数写成 1.111 来注意哪些位是小数,哪些是整数。

    我们使用这种方法的原因是普通的整数算术运算符仍然有效。

    【讨论】:

      【解决方案2】:

      将定点数视为缩放整数是最简单的,而不是移位整数。对于给定的定点类型,有一个固定的 scale,它是 2(或 10)的幂。要将实际值转换为整数表示,请乘以该比例。要再次转换回来,只需除法即可。那么如何表示负值的问题就变成了您用来表示数字的整数类型的细节。

      请任何人告诉我哪个来源是正确的......

      两者都有问题。

      您的第一个source 不正确。给定的例子是 not...

      与 2 的补数相同。

      在二进制补码中,MSB(最高有效位)的权重被取反,但其他位仍然贡献正值。因此,所有位都设置为 1 的二进制补码数不会产生最小值。

      您的第二个 source 可能会有点误导...

      将数字的位模式向右移动 1 位总是将该数字除以 2。

      该语句忽略了当 LSB(最低有效位)设置为 1 时发生的下溢问题,以及由此产生的舍入。右移通常导致向负无穷舍入,而除法导致向零舍入(截断)。两者对正数产生相同的行为:3/2 == 13>>1 == 1。对于负数,它们是相反的:-3/2 == -1-3>>1 == -2

      ...有符号定点数有标准表示吗?

      我不这么认为。有特定于语言的标准,例如ISO/IEC TR 18037 (draft)。但是,将整数缩放为近似预定范围和分辨率的实数的惯例已经确立。底层整数如何表示是另一回事。

      此外,如果 2 的补码表示是正确的,那么如何用零整数部分表示负数。比如-0.125?

      这取决于您的整数格式和您选择的基数。假设一个 16 位二进制补码数表示二进制定点值,比例因子为 2^15,即 32,768。将要存储为整数的值相乘:-0.125*32768. == -4096,然后除以检索它:-4096/32768. == -0.125

      【讨论】:

      • 如果将-0.125转换为8位整数部分和8位小数部分的定点数,如何计算?
      • @Chris 那么你有 7 位而不是 15 位(不包括“符号”位),所以比例为 2^7 == 128。从值到整数的转换是-0.125*128. == -16,从整数到值的转换是-16/128. == -0.125
      • 非常感谢。虽然我的计算方法和你的不同,但结果是一样的。我将整数和小数部分分别转换为两个 8 位整数,将它们组合为一个整数,将所有位反转并加一个(取反一个二进制补码)。
      猜你喜欢
      • 1970-01-01
      • 2015-08-10
      • 1970-01-01
      • 2015-06-25
      • 2021-12-06
      • 1970-01-01
      • 1970-01-01
      • 2011-04-26
      • 2018-04-10
      相关资源
      最近更新 更多