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*)
是一个强制类型转换,将其转换为指向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格式。)
- 这不是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, 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*
}