使用int指针的float的位表示形式

时间:2018-09-30 14:08:51

标签: c++ floating-point

我进行以下锻炼:

  

将一个函数void float浮动到bits(float x),此函数将打印该位   x的表示形式。提示:将float转换为int会截断   小数部分,但不会丢失任何信息,将浮动指针强制转换为   一个int指针。

现在,我知道浮点数由一个符号位表示,一些位表示尾数,一些位表示基数,一些位表示指数。这取决于我的系统使用多少位。

我们在这里面临的问题是我们的人数基本上有两部分。让我们考虑一下8.7这个数字的位表示形式(据我了解):1000.0111

现在,浮点数以前导零存储,因此8.8将变成0.88*10^1

因此,我必须以某种方式将所有信息移出我的记忆。我真的不知道该怎么做。那应该提示我什么?整数指针和浮点指针有什么区别?

目前我有这个:

void float_to_bits() {
    float a = 4.2345678f;
    int* b;
    b = (int*)(&a);
    *b = a;

    std::cout << *(b) << "\n";
}

但是我真的没有在这里得到暗示的帮助。如何获取尾数,指数,符号和基数?我还尝试使用按位运算符>>,<<。但是我只是看不到这对我有什么帮助,因为它们不会改变指针的位置。获得例如整数的位表示形式,仅此而已,不知道在这里使用什么。

2 个答案:

答案 0 :(得分:4)

您的老师给出的提示具有误导性:最好在实现中定义不同类型之间的指针。但是,如果定义了memcpy(...),则将对象unsigned char设置为大小合适的数组。如果生成的数组可以将内容分解为位。这是一个使用十六进制值表示位的快速技巧:

#include <iostream>
#include <iomanip>
#include <cstring>

int main() {
    float f = 8.7;
    unsigned char bytes[sizeof(float)];
    std::memcpy(bytes, &f, sizeof(float));
    std::cout << std::hex << std::setfill(‘0’);
    for (int b: bytes) {
        std::cout << std::setw(2) << b;
    }
    std::cout << ‘\n’;
}

请注意,除非规范化值外,IEEE 754二进制浮点不会存储完整的有效位(标准不使用尾数作为术语)浮动商店

  • 1位标志
  • 指数的8位
  • 归一化有效位数的23位,暗含非零高位

答案 1 :(得分:2)

提示将指导您如何在不进行值转换的情况下将Float传递给Integer。
当您将浮点值分配给整数时,处理器将删除分数部分。 int i = (int) 4.502f;将导致i = 4;

但是当您将一个int指针(int*)指向一个浮点数的位置时, 甚至当您读取int*值时,也不会进行任何转换。

要显示表示形式,我喜欢看到十六进制数字,
这就是为什么我的第一个例子在十六进制中给出的原因
(每个十六进制数字代表4个二进制数字。)

,但也可以打印为二进制,
而且有很多方法(我最喜欢这一方法!)

遵循带注释的示例代码:
也可用@ Culio

#include <iostream>
#include <bitset>
using namespace std;

int main()
{
   float a = 4.2345678f; // allocate space for a float. Call it 'a' and put the floating point value of `4.2345678f` in it.
    unsigned int* b; // allocate a space for a pointer (address), call the space b, (hint to compiler, this will point to integer number)
    b = (unsigned int*)(&a); // GREAT, exactly what you needed! take the float 'a', get it's address '&'.
    //                          by default, it is an address pointing at float (float*) , so you correctly cast it to (int*).
    //                          Bottom line: Set 'b' to the address of a, but treat this address of an int!

    // The Hint implied that this wont cause type conversion:
    // int someInt = a; // would cause `someInt = 4` same is your line below:
    // *b = a; // <<<< this was your error.
    // 1st thing, it aint required, as 'b' already pointing to `a` address, hence has it's value.
    // 2nd by this, you set the value pointed by `b` to 'a' (including conversion to int = 4);
    // the value in 'a' actually changes too by this instruction.

    cout << a << " in binary " << bitset<32>(*b)  << endl;
    cout << "Sign    " << bitset<1>(*b >> 31) << endl; // 1 bit (31)
    cout << "Exp     " << bitset<8>(*b >> 23) << endl; // 8 bits (23-30)
    cout << "Mantisa " << bitset<23>(*b) << endl; // 23 bits (0-22)
}