【问题标题】:get the integer representation value of a float type variable in C获取C中浮点类型变量的整数表示值
【发布时间】:2016-03-21 07:54:29
【问题描述】:

我将数字 20 (0x14) 存储在 32 位寄存器中。该寄存器被分配给一个表示值 2.8e-44 的 C 浮点变量。现在我想取回浮点变量的十六进制表示并将其存储到一个整数变量中,以恢复信息的原始含义。除了做一些指针业务之外,还有更好的方法吗?代码如下:

#include <stdio.h>

int main()
{
    float f = 2.802597e-44;
    int nv,*pnv;
    printf("f=%f\n",f);
    printf("n=%d\n",f);
    nv=(int)f;
    printf("n=%d\n",nv);
    pnv=(int*)&f;
    printf("n=%d\n",(*pnv));
    return 0;
}

我使用 pnv 整数指针得到我想要的。有没有更好的方法来避免使用指针并在 C 中工作?

【问题讨论】:

  • float type register 那是什么?
  • printf("n=%d\n",f); 是 UB。
  • 浮点型变量中的值 20 在哪里?我在f 中只能看到接近 0 的数字。
  • 您 (i) 是否要将 float 转换为整数(即​​在转换允许的范围内保留数值),还是要处理 内存 与float 关联作为一个整数?
  • @Jens 2.8e-44 的十六进制表示为 0x14。检查[链接]h-schmidt.net/FloatConverter/IEEE754.html

标签: c floating-point


【解决方案1】:

您可以通过工会满足您的需求:

#include <stdio.h>

int main()
{
  union { int i; float f; } fi;
  fi.f = 2.802597e-44;
  printf("f=%e\n",fi.f);
  printf("n=%d\n",fi.i);
  return 0;
}

【讨论】:

  • 工作得很好,为了完整起见,我添加了 nv = ((int)&f),我会将您的答案标记为正确。
  • @lalamer "添加 nv = ((int)&amp;f) 以确保完整性" --> 什么?这不是好的编码。
【解决方案2】:

注意(int*)&amp;f 的行为是未定义,因为指针类型是不相关的。所以不要这样处理问题。

确认sizeof(float)sizeof(int) 相同后,您可以通过以下两种方式之一进行操作:

1) 通过由floatint 组成的union 进行类型修剪。使用一个成员设置union,并与另一个成员一起读回。

2)memcpy将一种类型变量的内容转移到另一种类型变量的位置。

其中我更喜欢 (2):(1) 可能在较旧的 C 标准中未定义,并且 (2) 也适用于 C++。

【讨论】:

  • memcpy 实际上和指针一样。为了完整性,您能否建议一个联合技巧的代码示例。你可以修改我的代码。
  • 不,memcpy 是一回事。 memcpy 是标准定义的,你改变指针类型的方式是not
  • 由哪个标准定义?提供参考。
  • @M.M 感谢您的参考。我正在阅读 ISO9899:1999,因为我使用的是兼容 C99 的编译器。 6.5.7 被命名为“按位移位运算符”并且没有提到 memcpy。你还有别的意思吗?
  • @Bathsheba:虽然memcpy 是由标准定义的,但从float 复制到int 的内容的解释却不是,就像指针逻辑一样。
【解决方案3】:

您可以直接将其转换为整数;

float a = 7.4;
int b = a; // this will be rounded to 7 and you will lose information

或者您可以使用一些内置函数,如round、ceil、floor 等。

供参考:http://www.cplusplus.com/reference/cmath/round/?kw=round

【讨论】:

  • 虽然技术上是正确的,但您提出的 anser float a = 7.4; int b = a; 并不是这个问题的答案。
【解决方案4】:

你可以使用类型转换..

float x =3.4;
int y = (int)x;

【讨论】:

    【解决方案5】:

    Undefined Behavior,你在做什么,你没有检查警告吗?

    warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘double’ [-Wformat=]
         printf("n=%d\n",f);
         ^
    

    请阅读:How do the digits 1101004800 correspond with the number 20?

    【讨论】:

    • h-schmidt.net/FloatConverter/IEEE754.html 并检查十六进制表示,然后将 0x14 转换为十进制。
    • @lalamer 很好,请查看我的更新答案,感谢您的支持,您也从我这里得到了它。
    【解决方案6】:

    C 被认为是一种弱类型语言,它可能允许分配属于与分配它们的变量不同类型的值,因此您可以简单地这样做:

     int integer = 1;  
     float floater =1.1111;
    
     floater = integer;  
    

    这称为隐式类型转换,也称为强制转换,是 编译器的自动类型转换。一些编程 语言允许编译器提供强制;其他人需要它。

    但请考虑以下几点:

    • 当浮点数小于零时会发生什么?

    【讨论】:

    • 什么是Serial.println()
    • @mouviciel,它特定于我的 C IDE 使用的串行窗口,它只是在类似控制台的窗口上打印值!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-16
    • 2011-02-02
    • 1970-01-01
    • 1970-01-01
    • 2020-12-12
    • 1970-01-01
    相关资源
    最近更新 更多