我正在使用浮点数在C中执行一些计算。我特别处理的是我得到指数的最低单精度值的情况。
说我的指数是-126,我必须减少它。在这种情况下,我不能再低了,所以我需要右移我的尾数一次。我知道我应该得到计算的确切答案,然后回合(到指定的任何地方)。
我正在考虑做(让M
成为尾数):
M >>= 1;
//round mantissa
因为我将尾数移到右边并且浮点左边有一个隐含的1,我是否需要在移动之后修改M:
M |= (1 << 23)
确保我有一个最重要的位?
在丢失一些信息之后回合似乎很奇怪但是这个标准/接受的做法是什么?或者我应该使用更多位和然后舍入来计算完整结果?
答案 0 :(得分:1)
对于浮点数,有#34;法线&#34;和#34; de-normals&#34;。
对于&#34;法线&#34;尾数有一个隐含的1位,值为( 1 + (mantissa >> mantissa_bits) ) << (exponent_value - exponent_bias)
。
&#34; de-normals&#34;尾数没有隐含的1位,指数始终是其最小值(或者比法线的最小值小1),值为(mantissa >> mantissa_bits) << (0 - exponent_bias)
或mantissa >> (exponent_bias + mantissa_bits)
。
对于非法线,当你向右移动时,指数保持不变,而尾数则转移。最低有效位将丢失,但用于舍入尾数(根据舍入模式)。例如。 (假设舍入到最近)1011001b >> 5 = 10.11001b = 11b
和1001001b >> 5 = 10.01001b = 10b
。
请注意,反常规很烦人,需要特殊情况处理来影响性能;所以大多数现代CPU有一个特殊的&#34; de-normals是零&#34;模式(不符合IEEE标准),只需用+/- 0替换任何非法线。
如果你在软件中这样做,使用更大的浮点格式(精度更高)进行所有计算可能会更快,并忽略去法线(这会降低微小数字的精度)以最少的头痛来达到相同的精度。如果有必要,你可以在没有去常规的情况下进行转换。并且&#34;小于正常值&#34;格式。特别;我很想尝试使用64位尾数和32位指数而不会出现正常情况,例程可以在这种内部格式之间转换为32位浮点数&#34;和#34; 64位双&#34;。