使用 int 指针的浮点数的位表示形式

Bit representation of float using an int pointer

本文关键字:表示 浮点数 int 指针 使用      更新时间:2023-10-16

我有以下练习:

实现一个函数 void float to bits(float x( 来打印位 提示:将浮点数转换为 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";
}

但我真的不明白这里的提示背后的大局。如何获得尾数、指数、星座和基数?我还尝试使用按位运算符>>,<<。但我只是看不出这应该如何帮助我,因为他们不会改变指针位置。例如,获取整数的位表示很有用,但仅此而已,不知道它在这里有什么用。

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

#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 二进制浮点不存储完整的有效数(标准不使用尾数作为术语(,除了非规范化值:32 位浮点存储

  • 符号为 1 位
  • 指数为 8 位
  • 23 位表示归一化有效数,隐含非零高位

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

但是当你使一个整数指针(int*(指向浮点数的位置时, 不会进行任何转换,当您读取int*值时也是如此。

为了显示表示,我喜欢看到十六进制数字,
这就是为什么我的第一个示例是十六进制(每个十六进制
数字代表 4 个二进制数字(。

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

遵循带注释的示例代码:
也可用@库里奥

#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)
}