这是根据 IEEE-754 标准均衡两个不同数字的指数的正确方法吗?
Posted
技术标签:
【中文标题】这是根据 IEEE-754 标准均衡两个不同数字的指数的正确方法吗?【英文标题】:Is this the correct way of equalising exponents of two different numbers according to the IEEE-754 standard? 【发布时间】:2020-06-21 17:46:47 【问题描述】:我省略了尾数和符号位以及处理次法线、无穷大、NaN、-0.0。我只想先关注指数,然后再关注其余部分。
#include <stdio.h>
#define N 23
int binary(int n);
int exp_diff(int exp1, int exp2);
32位结构,1位符号,8位指数,23位尾数
union
unsigned int result;
struct
unsigned int mantissa: 23;
unsigned int exponent: 8;
unsigned int sign: 1;
value;
fps;
int main(void)
int num1 = 3;
int num2 = 5;
int exp1 = 0;
int exp2 = 0;
exp1 = binary(num1);
exp2 = binary(num2);
fps.value.exponent = 127 + exp_diff(exp1,exp2);
printf("%08x\n", fps.result);
return 0;
将值转换为二进制并返回指数
int binary(int n)
int i = 0;
int remainder = 0;
int a[N] = 0;
while(n > 0)
a[i++] = n % 2;
n /= 2;
return i - 1;
通过判断 epx1 是否小于 exp2 来均衡指数,反之亦然
int exp_diff(int exp1, int exp2)
if(exp1 < exp2)
return exp2 - exp1;
else if(exp2 < exp1)
return exp1 - exp2;
【问题讨论】:
将N
重命名为MANTISSA_NBITS
之类的名称,然后在实际位域中使用它会不会更清楚一些?
您的exp_diff
需要在底部添加一个return 0
。或者,只需消除 else if
并执行:if (exp1 < exp2) return exp2 - exp1; else return exp1 - exp2;
在binary()
中,我不太明白a[N]
数组的用途;该值已设置,但从未使用过,因此您真正需要的可能只是i++
。您是否使用最大编译器警告编译了代码(这可能也会指出@CraigEstey 指出的项目)。
【参考方案1】:
使用位域访问浮点表示的内部域是有问题的,因为 C 标准在位域的布局方面为实现留下了很大的灵活性。更好的方法是使用位移和屏蔽操作。假设 float
是 32 位并且包含 <stdint.h>
:
typedef struct unsigned sign, exponent, significand; FloatFields;
FloatFields DecodeFloat(float x)
uint32_t u;
memcpy(&u, &x, sizeof u);
return (FloatFields)
u >> 31,
u >> 23 & 0xff,
u & 0x7fffff,
;
float EncodeFloat(FloatFields Fields)
uint32_t u = Fields.sign << 31 | Fields.exponent << 23 | Fields.significand;
float f;
memcpy(&f, &u, sizeof f);
return f;
关于代码fps.value.exponent = 127 + exp_diff(exp1,exp2);
,不清楚它是否有任何用处。它为指数提供编码,其表示(未编码)值是操作数指数之间的绝对差异。例如,如果操作数是 1.5•27 和 1.1259,它提供了指数 2 的编码。那有什么用?也许您正试图腾出空间来定位操作数的有效数字,并在它们之间进行所需的移位,但尚不清楚您将如何使用它。根据现有的信息,总的来说,我想说这不是“使指数相等”的正确方法。
【讨论】:
以上是关于这是根据 IEEE-754 标准均衡两个不同数字的指数的正确方法吗?的主要内容,如果未能解决你的问题,请参考以下文章