C - 这段代码正在提取尾数,指数,但为什么我们一开始使用 PTR,PTR 一开始的价值是什么?0?


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中,&是产生其操作数地址的一元操作符,因此&numbernumber的地址。这是一个指向float的指针。

那么(unsigned int*)是一个强制类型转换,将其转换为指向unsigned int的指针。

然后使用*ptr使用这个指针从地址中获得unsigned int。这样做的目的是将编码float的位从内存中加载并解释为unsigned int,从而允许使用>>&运算符对这些位进行操作。

通过使用unsigned int x; memcpy(&x, &number, sizeof x);代替,C和c++标准确保表示number的字节被复制到x中。这避免了语言标准中的各种限制和语义问题。它确实要求unsigned int是所需的大小,32位。(代码还期望float使用IEEE-754 binary32格式。)

  1. 这不是C代码
  2. 它使用可怕的指针双关语-违反严格的混叠规则

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, int *m, int *e, float number )
{
unsigned int unum ; 
memcpy(&unum, &number, 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*
}

相关内容

最新更新