【问题标题】:floating point constant in C, bit representationC中的浮点常量,位表示
【发布时间】:2015-06-18 10:58:57
【问题描述】:

在 C 中可以访问浮点常量的位表示;

例如我想分配

uint64_t x = //bit representation of 5.74;

表示为 0x40b7ae14

你认为有可能吗?

【问题讨论】:

  • uint64_t x = 0x40b7ae14; 会起作用。
  • float x = 5.74; uint32_t y; memcpy(&y, &x, sizeof(y)); 请注意,float 通常是 32 位,而不是 64 位。
  • 是的,我知道...但我的问题是是否可以直接说“从 5.74 推断 0x...”。
  • @EOF,我会尝试,但我认为 5.74f 是“浮点值”,而没有“f”,它应该被视为 double 不是吗?
  • @Lukkio:是的,但它是通过分配给float-变量来隐式转换的。

标签: c types floating-point constants


【解决方案1】:

实现此目的的一种方法是使用联合:

union {
    double fltValue;
    uint64_t uintValue;
} conversion;

conversion.fltValue = 5.74;
printf("%#llx\n", conversion.uintValue);

更新 %#x 感谢 Aracthor 提及。 %#llx 感谢 EOF。

有关工作示例(使用float 而不是double)请参阅:

https://ideone.com/p4rH5l

【讨论】:

  • 你的printf()错了,打印64位数字时需要"%#"PRIx64"\n"
  • @SergeBallesta 我在C标准(C11)中找了这个限制,没找到,可能是我看错地方了,还以为已经从标准。不过我相信你的话。
  • 根据 EOF 的评论更改了之前的评论。摘自 C99 草案 6.2.6.1:当一个值存储在联合类型对象的成员中时,对象表示中不对应于该成员但对应于其他成员的字节采用未指定的值我>。它不是明确的 UB,因此不应该被优化掉,但是 C 没有指定其他成员的值应该是什么。
  • 对不起,我的 C-standard-foo 有点弱,相关部分实际上是一个脚注:Section 6.5.2.3 §3, footnote 95): If the member used to read the contents of a union object is not the same as the member last used to store a value in the object, the appropriate part of the object representation of the value is reinterpreted as an object representation in the new type as described in 6.2.6 (a process sometimes called ‘‘type punning’’). This might be a trap representation.
【解决方案2】:

这是可能的,但不可移植,因为您无法确定浮点值是如何表示的:C 标准没有定义它。

您可以简单地使用指针转换:

float x = 5.74;
void *pt = &x
uint64_t *ip = pt;
uint64_t i = *ip;

这是正式的未定义行为,因为您将指针转换为不同的类型,并且您不应该这样做,因为您将字节序问题添加到浮点表示。

正确的方法是:

float x = 5.74;
void *pt = &x
unsigned char *ip = pt;

ip 现在指向大小为sizeof(float)unsigned char[],其中包含浮点数的二进制表示。并且没有调用未定义的行为,因为始终允许将指针转换为 void *char *

【讨论】:

    【解决方案3】:
    #include <stdint.h>
    #include <stdio.h>
    
    int main(void) {
        double x = 5.74;
        uint64_t y = *((uint64_t*)&x);
        printf("0x%016llx", y);  /* 0x4016f5c28f5c28f6 */
    }
    

    【讨论】:

    • 仅代码的答案是不受欢迎的。请扩展您的答案,并解释您的代码如何解决 OP 的问题。
    【解决方案4】:

    如果你要求浮点数的二进制表示,那么取一个整数指针..将浮点变量的地址分配给整数指针,并通过取消对 int 指针的值的引用,得到它的二进制形式..并在中间如果你想避免异常类型转换产生的警告,那么你总是可以使用 void*

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多