我是编程新手,我已经完成了Web开发,但我目前正在尝试学习真正的编程。我的问题已经回答here。
union ufloat {
float f;
unsigned u
};
ufloat u1;
u1.f = 0.3f;
我不知道它是如何工作的。 0.3
部分做了什么?我在文中找不到它。这如何将浮点数转换为二进制?因为cout<<u1.u;
似乎没有给我答案。有人可以帮忙吗?
答案 0 :(得分:3)
0.3
只是一个测试值。打印u1.u
不会为您提供二进制表示,但二进制表示的值被解释为基数为10的整数。要获取二进制值,您必须convert u1.u
为二进制值。
转换的另一种方法是使用bitwise operators。
例如:
unsigned x = 11;
do
{
cout << (x & 1); // print last bit
x = x >> 1; // get rid of the printed bit
} while ( x );
请注意,这将以相反的顺序打印位(最不重要的是先打印)。我将由你来解决这个问题(你可以在数组中使用递归或存储值,然后反转打印数组)。
我还建议您阅读unions。基本上,unsigned
将占用与float
相同的内存空间,允许您规避使用按位运算符查找float
的二进制表示的限制。
答案 1 :(得分:2)
答案在于工会如何在C / C ++中运作。联合允许您使用内存中的相同空间表示多种类型的数据。因此,在您的示例中,ufloat
联合将float和整数存储在同一内存空间中。根据您访问此内存空间的方式(通过f
数据成员或u
数据成员),程序将分别将内存区域解释为浮点或无符号整数。
当您通过u
数据成员访问内存区域时,程序认为您希望将内存区域表示为二进制整数,而不是浮点值。但由于内存区域实际上存储了浮点值(0.3f),因此它只是输出该值,就像它是二进制整数一样。因此,您将获得浮动的二进制表示。
答案 2 :(得分:2)
过于迂腐,这不是有效的C或C ++。
我怀疑现有的每个编译器都支持它,但就标准而言,编写一个union的一个成员然后读另一个成员是无效的。但是,要知道float
和unsigned
大小相同,您已经使用了一些实现定义的信息,因此您可以使用更多信息。它很常见,而且通常都有效。
但是,作为参考,您始终可以将内存检查为一系列字节:
#include <iostream>
#include <iomanip>
#include <climits>
#include <cassert>
int main() {
float f = 0.3;
unsigned char *buf = (unsigned char*)(&f);
// Now we just have to print the sucker.
assert(CHAR_BIT == 8); // otherwise hex isn't much use
// This shows the byte representation, low addresses on the left.
// On a little-endian machine, you might like to count down for
// convenience of reading.
for (int i = 0; i < sizeof f; ++i) {
std::cout << std::hex << std::setw(2) << std::setfill('0');
std::cout << static_cast<unsigned int>(buf[i]) << ' ';
}
std::cout << '\n';
}
输出(在我的机器上):
9a 99 99 3e
如果您更愿意使用unsigned
而不是unsigned char
:
#include <cstring>
float f = 0.3;
unsigned u;
assert(sizeof f == sizeof u);
std::memcpy(&u, &f, sizeof f);
std::cout << std::hex << u << "\n";
输出(在我的机器上):
3e99999a