Linux gcc (5.4.0) 中的 float 是否遵守 IEEE754 规则?

Does float in Linux gcc (5.4.0) obey IEEE754 rules?

我的编程环境是 gcc 版本 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4)

我这样编码:

#include <stdio.h>

typedef unsigned char *byte_pointer;

void show_bytes(byte_pointer start, int len){
  int i;
  for (i = 0; i<len; i++)
    printf(" %.2x", start[i]);
  printf("\n");
}

void show_float(float x){
  show_bytes((byte_pointer)&x, sizeof(float));
}

int main(){
  int y = 0xffffff;
  float f = y;
  show_float(f);
  return 0;
}

机器给出结果:00 00 00 e0

我认为根据 IEEE 754 是不对的;但我不知道为什么。 而 windows 中 VS 2013 中的相同代码给出了正确的答案:ff ff 7f 4b

gcc 5.4.0 不是采用 IEEE 754 吗? 还是我的代码有问题?

gcc 没有使用不同的单浮点表示法,而是在程序的某处将其提升为双精度浮点数。转换可能发生在调用 show_bytes 时,但也可能发生在其他地方。如果您将浮点数更改为双精度数,您可能会再次得到相同的错误输出,它可能会使用两种编译器。

这可能是 gcc 的错误或优化,但这不是 c 编译器的正常行为,请参阅 this question

#include <stdio.h>

typedef unsigned char *byte_pointer;

void show_bytes(byte_pointer start, int len) {
    int i;
    for (i = 0; i<len; i++)
        printf(" %.2x", start[i]);
    printf("\n");
}

void show_float(double x) {
    show_bytes((byte_pointer)&x, sizeof(float));
}

int main() {
    int y = 0xffffff;
    double f = y;
    show_float(f);
    return 0;
}

这输出

00 00 00 e0

如果您在输出错误的程序中将 sizeof(float) 更改为 sizeof(double),您将能够看到整个 double 以验证这一点

对我来说使用双打我得到

00 00 00 e0 ff ff 6f 41

Does gcc 5.4.0 not adopt the IEEE 754?
Or are there some problem in my code?

gcc 5.4.0 和 IEEE 754 不是问题。当然代码不符合


通过重新排序函数,但代码相同,我收到 2 个警告并且可以复制 OP 的输出 00 00 00 e0

警告:函数的隐式声明'show_float'[-Wimplicit-function-declaration]
警告:'show_float'

的类型冲突

我怀疑OP没有发布真实代码。 - 或者它不是全部在一个文件中。实际代码通常存在代码传递问题 double - 由于缺少先验 declaration/definitioon,但 show_float() 需要 float.

#include <stdio.h>

typedef unsigned char *byte_pointer;

void show_bytes(byte_pointer start, int len){
  int i;
  for (i = 0; i<len; i++)
    printf(" %.2x", start[i]);
  printf("\n");
}

int main(){
  int y = 0xffffff;
  float f = y;
  show_float(f);  // code lacks proto-type, so assumes it needs to pass a double
  return 0;
}

void show_float(float x){
  show_bytes((byte_pointer)&x, sizeof(float));
}

通过声明原型或重新排序代码来修复。

#include <stdio.h>

typedef unsigned char *byte_pointer;
void show_bytes(byte_pointer start, int len);
void show_float(float x);

/* the 3 functions in any order */