C 双精度的符号、尾数和指数

C 双精度的符号、尾数和指数,c,floating-point,C,Floating Point,我从中找到了以下代码 #包括 typedef联合{ 浮动f; 结构{ 无符号整数mantisa:23; 无符号整数指数:8; 无符号整数符号:1; }零件; }双U型铸造; int main(){ 双U型铸造d1; d1.f=0.15625; printf(“符号=%x\n”,d1.parts.sign); printf(“指数=%x\n”,d1.parts.exponent); printf(“mantisa=%x\n”,d1.parts.mantisa); 返回0; } 但是我如何将它转换

我从中找到了以下代码

#包括
typedef联合{
浮动f;
结构{
无符号整数mantisa:23;
无符号整数指数:8;
无符号整数符号:1;
}零件;
}双U型铸造;
int main(){
双U型铸造d1;
d1.f=0.15625;
printf(“符号=%x\n”,d1.parts.sign);
printf(“指数=%x\n”,d1.parts.exponent);
printf(“mantisa=%x\n”,d1.parts.mantisa);
返回0;
}

但是我如何将它转换为尾数为52、指数为11、符号为1的双精度数呢?

只要扩展逻辑并定义您的并集,使用标准int 64实现可移植性:

#include <stdint.h>

typedef union {
  double f;
  struct {
    uint64_t mantisa : 52;
    uint64_t exponent : 11;
    uint64_t sign : 1;
  } parts;
} double_cast;

我认为应该使用bit和shift操作符从double/float中提取字段。您可以为此制作宏/函数。

谢谢,长期以来的声明是什么?对于8个字符的值呢?
long
可以是8个字节,也可以是4个字节,或者其他什么,这就是为什么
存在的原因:提供具有定义大小的统一类型。这不是非常可移植的,因为C标准没有限制位字段的布局。@OregonState2016,您的整个方法是不可移植的。您不能依靠联合来将位字段映射到
浮点
/
双精度
的位,就像您希望的那样。@OregonState2016,是的,事实上。函数的
frexp()
系列专门用于分隔浮点数的符号+尾数和指数部分。从那里到你想去的地方相当简单。不要忽略一个事实,即标准化IEEE-754 FP编号的尾数中有一个额外的隐含1位,您可能需要对此进行说明。按位运算符仅适用于整数类型,而不适用于
浮点型
双精度
,使用指针访问一个类型的对象,就像它是另一个类型的对象一样,调用未定义的行为。有一些例外,但这里唯一适用的例外是通过
char*
无符号char*
访问实际值。这可能行得通,但它比简单的移位/屏蔽/完成要复杂得多。
#include <stdint.h>

typedef union {
  double f;
  struct {
    uint64_t mantisa : 52;
    uint64_t exponent : 11;
    uint64_t sign : 1;
  } parts;
} double_cast;
typedef union {
  float f;
  struct {
    uint32_t mantisa : 23;
    uint32_t exponent : 8;
    uint32_t sign : 1;
  } parts;
} float_cast;