我进行以下锻炼:
将一个函数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";
}
但是我真的没有在这里得到暗示的帮助。如何获取尾数,指数,符号和基数?我还尝试使用按位运算符>>,<<。但是我只是看不到这对我有什么帮助,因为它们不会改变指针的位置。获得例如整数的位表示形式,仅此而已,不知道在这里使用什么。
答案 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 :(得分: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)
}