如何规范两个IEEE754单精度数字之和?

时间:2018-12-14 03:10:57

标签: floating-point verilog system-verilog ieee-754 twos-complement

我正在设计SystemVerilog中的浮点单元,该单元采用两个IEEE754格式的32位输入,将它们加在一起,然后以相同的32位IEEE754格式输出结果。

我的问题是,如何判断我的结果是否需要归一化?

我意识到这是当您需要将“最左边的” 1移动到正确的位时,该位应该是第23位(从位0开始)

我头疼的是,如何确定正确的“最左边”的1位是什么,以便我可以移动尾数​​并适当地增加/减少指数位。

如果我的理解是正确的,则加法应遵循以下过程。

  • 将位分成符号,指数和尾数
  • 在尾数前加上“ 1”
  • 比较指数并将差值添加到较小的指数
  • 通过所述差将较小指数的尾数向右移动以正确地“排列”小数/数字
  • 执行二进制加法
  • 如有必要,对结果进行归一化

我相信除了规范化部分正确之外,我已经采取了所有措施。我的问题是,如果我只有位,如何确定结果未归一化?

我知道,如果结果不是1.(分数),则无法归一化。
即。应该将10.10101 * 2 ^ 1标准化为1.010101 * 2 ^ 2,并将.1001 * 2 ^ 2标准化为1.001 * 2 ^ 1。

具体来说,我想我想问一个加两个数字后如何跟踪“小数”位置在哪里。

例如:添加输入a:0x3fc00000(1.5)和b:0x40500000(3.25)

a = 0 | 0111 1111 | (1)100 0000 0000 0000 0000 0000
b = 0 | 1000 0000 | (1)101 0000 0000 0000 0000 0000

a的指数小于b的差1,因此:

a = 0 | 1000 0000 | 0(1)10 0000 0000 0000 0000 0000
b = 0 | 1000 0000 | (1)101 0000 0000 0000 0000 0000

加上尾数会给我们结果

1 0011 0000 0000 0000 0000 0000

在这里,我们看到“最左边的” 1是第24位,而不是第23位,因此我们将尾数向右移动1并增加指数以对结果进行归一化。然后我们删除“最左边的” 1,因为它以IEEE754格式隐含,我们得到:

0 | 1000 0001 | 001 1000 0000 0000 0000 0000(4.75)作为我们的最终输出是正确的。

鉴于此示例,我认为我只需要检查以下情况:

  • 如果尾数的第24位等于1,则将尾数右移并增加指数
  • 否则检查位23为1,如果为true,则无需标准化
  • 否则校验位22为1,然后向左移动尾数并减小指数

但是,我仅在某些情况下才发现这是正确的。我想念什么?

在我的实现中,我做了一个26位的值来保存两个尾数的和,我不确定这是正确的。第25位是尾数的符号,我并不是我真正需要的,而第24位和第23位是隐藏位,或者最终输出中将不包含的位。

例如:0x449ebbc8(1269.868163)+ 0xc60eb709(-9133.758561)给我以下尾数:

11 0111 1010 1101 1111 1001 0000请注意,这是26位(25:0)

如果我遵循前面的情况,那将意味着除符号位之外的“最左1”位将为24位,这意味着我将向右移动尾数并增加指数。但是正确的答案是相反的! “'真'最左边的1”位实际上是22位!意思是我应该左移并递减!给我最终的输出:

1 | 10001011 | 111 0101 1011 1111 0010 0000(-7863.8906)是正确的。

类似地,将0x45c59cbd和0xc473d9dc相加得出的尾数为

01 1010 0111 0010 0001 1000 0010,但“最左1”位不是第24位,而是第23位,因此不需要规范化。

为什么在第一种情况下我需要担心第24位,而在其他两种情况下却无需担心?是因为我在其他情况下添加了相反的符号吗?溢出问题?还是从根本上我还缺少其他东西?

感谢您的帮助,如果格式不正确,请谅解!

1 个答案:

答案 0 :(得分:2)

请考虑以IEEE-754基本32位二进制格式添加两个正数。当它们的有效位数 1 通过在前导位加上前缀完成,移位以对齐指数并相加后,前导位要么在同一位置(因为未发生进位),要么在左边(因为发生)。要对此进行标准化,只需在发生进位时向右移一位。

(如果两个数字都为次正规数,则前导位可能在右边。但是,将不会进行归一化,因为结果将被带入使其变为正常的位置(因此不需要归一化),或者没有保持在该位置[因此结果仍然是次标准的,无法归一化。)

如果两个数字均为负,则情况相同。有效数字可被视为绝对值,而忽略符号位。

如果数字相反,则表示并发症。该问题描述了将符号位前缀到有效位。这似乎不会导致正确的结果。例如,考虑添加+1.125和−1.125。每个数字的四位有效位数为1001。将符号位前缀分别给我们01001和11001。然后将其相加得到1 00010(新的最左边的数字来自前一个最左边位置的进位)。不管我们如何处理前导位,低位都是错误的-0010不正确;由于+1.125 + −1.125 = 0,结果应为0000,且带有一些符号。因此,仅将符号位前缀为有效位是不正确的过程。

我记得关于实现浮点加法的所有描述都指定了在符号相反时使用减法而不是加法。在这种情况下,必须从较大(或相等)的数字中减去较小(或相等)的数字,然后必须向左移一些位数(可能为零)。

在此模型中,确定如何对数字进行标准化变得更简单:

  • 在添加类似符号的数字时,归一化要求根据从高位是否有进位来向右移零或一位。 (请注意,可能会发生指数溢出。)
  • 当减去对号时,归一化要求向左移动,直到前一位位于适当位置或达到最小指数为止。

我希望可以使用加法和二进制补码算法来实现混合符号的情况。在这种情况下,不仅应该在符号位之前加上符号位,还应通过将每个位取反然后加一个来形成符号位的补码。一旦找到总和,如果它是负数,则可以再次加2,然后归一化。但是,您随后要在实现中添加更多的带有进位链依赖性的添加项。

请注意,您还必须考虑对结果进行四舍五入的情况,因为在进行移位之前,为了对齐指数,在移位过程中可能会丢失一些位,而在进行移位时,对相似符号号进行归一化的结果可能会丢失一些位。

脚注

1 “有效位数”是浮点数小数部分的首选术语。 “ Mantissa”是对数的小数部分的历史术语。有效数字是线性的(将有效数字加倍,将表示的值加倍),而尾数是对数的(线性尾数加倍,则表示的值的一部分)。