首页 > 解决方案 > 对 C++ 中的无符号短行为感到困惑

问题描述

我目前正在尝试学习 C++。我通常通过玩东西来学习,因为我正在阅读数据类型,然后你可以声明整数的值(十进制、二进制、十六进制等),我决定测试“无符号短”是如何工作的. 我现在很困惑。

这是我的代码:

#include <cstdio> 

int main(){
  unsigned short a = 0b0101010101010101;
  unsigned short b = 0b01010101010101011;
  unsigned short c = 0b010101010101010101;
  printf("%hu\n%hu\n%hu\n", a, b, c);
}

“unsigned short”类型的整数在所有操作系统中的大小都应为 2 个字节。我使用二进制来声明这些整数的值,因为这是使我的困惑根源显而易见的最简单方法。

整数“a”有 16 位二进制数。16 位(2 字节)大小的数据类型中的 16 位。当我打印它时,我得到了数字 21845。看起来还可以。退房。

然后它变得很奇怪。

整数“b”有17 位数字。当我们打印它时,我们得到整个 17 位数字43691 的十进制版本。占用17位的二进制数如何适合应该只分配16位内存的变量?有人在撒谎吗?这是某种编译器魔法吗?

然后它变得更加奇怪。整数“c”有18位数字,但在这里我们达到了上限。当我们构建时,我们得到以下错误:

/home/dimitrije/workarea/c++/helloworld.cpp: In function ‘int main()’:
/home/dimitrije/workarea/c++/helloworld.cpp:6:22: warning: large integer implicitly truncated to unsigned type [-Woverflow]
   unsigned short c = 0b010101010101010101;

好的,所以我们可以将 17 位数字放入 16 位中,但我们不能放入 18 位。我猜这有点道理?就像我们可以魔术掉一个数字,但两个不会工作。但是假定的“截断”,而不是截断到实际最大值,17 位(或本例中的 43691),截断到逻辑上应该是的限制,21845。

这让我的大脑有些煎熬,我对整个兔子的了解太深了,现在不能停下来。有谁明白为什么 C++ 会这样?

- -编辑 - -

所以在有人向我指出我的二进制数以 0 开头之后,我意识到我很愚蠢。

但是,当我从左侧取出 0 并将其向右携带时(意味着 a,bc 实际上分别为 16,17,18 位),我意识到截断行为仍然没有意义。这是输出:

43690 21846 43690

43960 是 16 位的最大值。在问原始问题之前,我可以检查一下并节省一些时间。

为什么 17 位截断为 15,而 18(还有 19、20、21)截断为 16?

--编辑 2---

我已将整数中的所有数字都更改为 1,现在我的错误是有道理的。我得到了 65535。这次我花时间在计算器中输入了 2^16。我的整个问题都是因为我没有正确查看我分配的二进制值。

感谢链接隐式转换的人,我会阅读的。

标签: c++

解决方案


在大多数系统上,无符号短是 16 位。无论您为 unsigned short 分配什么,它都会被截断为 16 位。在您的示例中,第一位是 0,基本上被忽略了,同样的方式int x = 05;将等于 5 而不是 05。

如果将第一位从 0 更改为 1,您将看到赋值的预期行为将值截断为 16 位。

unsigned short int(16 位)的范围是 0 到 65535

65535 = 1111 1111 1111 1111 二进制


推荐阅读