问题描述
void getSME( int& s,int& m,int& e,float number )
{
unsigned int* ptr = (unsigned int*)&number;
为什么这个代码和 ptr 带有数字?这是必要的吗? ptr 当前值是多少?这不会导致 0
s = *ptr >> 31; *getting the sign bit*
e = *ptr & 0x7f800000;masking with exponent**
e >>= 23;then extracting the exponent**
m = *ptr & 0x007fffff;*extracting mantissa*
}
解决方法
虽然您已经标记了 C,但这是 C++ 代码,而不是 C。
unsigned int* ptr = (unsigned int*)&number;
尝试获取对 number
中的浮点值进行编码的位。但是,这在 C 或 C++ 中都不是正确的方法。更好的代码应该是 unsigned int x; memcpy(&x,&number,sizeof x);
。 (对于 C++,使用 std::memcpy
。)
在 &number
中,&
是产生其操作数地址的一元运算符,因此 &number
是 number
的地址。它是一个指向 float
的指针。
然后 (unsigned int*)
是一个强制转换,将 this 转换为指向 unsigned int
的指针。
然后使用 *ptr
使用此指针从地址中获取 unsigned int
。其目的是将编码 float
的位从内存中加载并解释为 unsigned int
,这允许使用运算符 >>
和 &
对这些位进行操作。
通过使用 unsigned int x; memcpy(&x,sizeof x);
,C 和 C++ 标准确保将表示 number
的字节复制到 x
中。这避免了语言标准中的各种限制和语义问题。它确实要求 unsigned int
是所需的大小,32 位。 (该代码还期望 IEEE-754 binary32 格式用于 float
。)
- 这不是 C 代码
- 它使用了可怕的指针双关语 - 违反了严格的别名规则
C 代码:
void getSME( int *s,int *m,int *e,float number )
{
union
{
unsigned int num;
float fnum;
}fu = {.fnum = number};
*s = fu.num >> 31; //*getting the sign bit*
*e = fu.num & 0x7f800000; //masking with exponent**
*e >>= 23; //then extracting the exponent**
*m = fu.num & 0x007fffff; //*extracting mantissa*
}
或
void getSME( int *s,float number )
{
unsigned int unum ;
memcpy(&unum,sizeof(unum));
*s = unum >> 31; //*getting the sign bit*
*e = unum & 0x7f800000; //masking with exponent**
*e >>= 23; //then extracting the exponent**
*m = unum & 0x007fffff; //*extracting mantissa*
}