这段代码正在提取尾数、指数,但为什么我们首先使用 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*) 是一个强制转换,将 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。)

,
  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,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*
}