unsign的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了unsign的问题相关的知识,希望对你有一定的参考价值。

16位系统中一个int能存储的数据的范围为-32768~32767,而unsigned能存储的数据范围则是0~65535 这个存储的数据的范围 指的是具体 int a; a的取值范围吗? int = 32768;这样就有问题?或者unsigned int = 65536这样也有问题么?但是我用VC++6.0 没有报错啊!郁闷~~

按VC++和C++的规定,int和long等长,都是32位的。short才是16位的。只有原始的C才定义int和short等长为16位。

这个数据范围指的确实是具体 int a;a的取值范围,但不是你理解的那样。
现在以16位的short为例。
首先必须清楚一个概念,计算机中存放的数据都是以二进制形式存放的。short存放的是整型数据,是用固定位数16个二进制位来表示一个整数,不足16位补0。
比如125的二进制是1111101,那么在内存中存放就是
0000 0000 0111 1101

那么16个二进制位能够表示多少种不同的整数呢?稍微用点数学常识就知道,是2的16次方,也就是65536个不同的整数。所以对于无符号整数,unsigned short的范围就是0~65535。
而为了表示负数,计算机用short的第一位作为符号位来表示正负。注意,计算机中是以补码的形式存放整数的。对于正数,补码是其本身;对于负数,其补码是对其绝对值的按位取反,再加1的结果。
举个简单的例子:
125是0000 0000 0111 1101
-125计算过程:
125是0000 0000 0111 1101
按位取反,1111 1111 1000 0010
再加1,1111 1111 1000 0011
所以-125就是1111 1111 1000 0011。
补码不是三言两语能讲得清楚的,楼主有个概念即可。
我们发现,正数的补码首位都是0,负数的补码首位都是1。
short有符号型的范围是-32768~32767。

那么,如果超出了范围,会发生什么现象呢?
很简单,这称为溢出。
比如short a = 32768
32768是1000 0000 0000 0000。还记得我讲过吗?正数的补码首位都是0,但这里首位为1,这是怎么回事呢?其实因为浪费了1位做符号位,short的有效位数只是15位而已,而2的15次方是32768,因此正数的范围是0~32767,32768超出了范围,计算机怎么处理呢?结果就是把它当作负数,根据补码计算它的原码。反过来即可
1000 0000 0000 0000 减1,
0111 1111 1111 1111 再按位取反,
1000 0000 0000 0000 就是32768
所以1000 0000 0000 0000表示-32768
也就是说short a = 32768;把a输出来得到-32768楼主可以试验一下。

再举一例:
unsigned short a=65536;
65536是1 0000 0000 0000 0000 注意这已经是17位了。计算机会自动截取后面的16位
就是得到0000 0000 0000 0000,也就是0
所以unsigned short a=65536;输出a得到0。
明白了吗?
参考技术A windows 98以后INT的定义都是4个字节,unsigned 时的值域是2的32次方。只有windows 3.1时代int 才是2个字节。
如果要用16位的整数,应该使用short
即使是unsigned short a=65536,程序也不会出错,只是自动取了模,执行上面这句话后a里面其实就变成了0.本回答被提问者采纳
参考技术B 因为你的电脑是32位操作系统。

SNMP 类型 Unsigned32 的正确编码是啥?

【中文标题】SNMP 类型 Unsigned32 的正确编码是啥?【英文标题】:What is the correct encoding for SNMP type Unsigned32?SNMP 类型 Unsigned32 的正确编码是什么? 【发布时间】:2012-05-25 14:55:26 【问题描述】:

我正在编写一个 SNMP 代理,并且 MIB 定义包含一个 Unsigned32 类型的 OID。

代理的 Unix 实现使用 Net-SNMP 并将 OID 设置为 ASN_UNSIGNED 类型,因为它没有 ASN_UNSIGNED32。当我使用 Wireshark 查看 GET 响应时,它会将其解码为“Gauge32”值。乍一看,这是有道理的,因为根据 RFC 1902,Unsigned32 和 Gauge32 是相同的。

Windows 实现基于 Windows 的 SnmpAPI.lib 并将 OID 设置为 ASN_UNSIGNED32,当我使用 Wireshark 查看 GET 响应时,它会将其解码为“Unsigned32”。这对我来说看起来更好。

为什么这 2 种实现会在线路上产生不同的结果?

哪个是正确的版本,我如何设法从两个实现中获得相同的版本?

【问题讨论】:

【参考方案1】:

事实证明,Net-SNMP 使用当前的 RFC 1902 编码,其中 Unsigned32 和 Gauge32 相同,而 Windows 使用过时的 RFC 1442 编码,其中 Unsigned32 和 Gauge32 具有不同的编码。

【讨论】:

好收获。听起来像是 Windows 的错误。 从表面上看,自 1996 年 RFC 1902 出现以来,Microsoft 并没有真正更新过 SNMP 服务。所以他们只是坚持旧版本,似乎大多数 SNMOP 工具仍然与 RFC 1442 兼容。【参考方案2】:

如果您在 Windows 上保存 Wireshark 捕获,然后在 Unix 上的 Wireshark 中打开它。然后你可能会看到它显示的类型是什么。 Unsigned32 和 Gauge32 在标准中定义是可以互换的,所以在所有的 SNMP 实现中应该没有什么不同。在网络上,它应该传输相同的字节。

【讨论】:

这就是我的想法,但是两个 Wireshark 跟踪都是在 Linux 上完成的,来自 Linux 代理的 OID 显示为 Gauge32,来自 Windows 代理的 OID 显示为 Unsigned32。在同一台机器上执行相同的 Wireshark。 没有时间深入研究 Wireshark 的解析器。但就像我说的那样,你应该阅读原始字节。你做到了吗?

以上是关于unsign的问题的主要内容,如果未能解决你的问题,请参考以下文章

关于unsigned char 型数据转换成十进制或者16进制的问题

将 unsigned short * 转换为 unsigned int *

怎样把unsigned short 转换为 unsigned char

unsigned int表示负数问题

ARDUINO 中将一个unsigned char 的数组的数据转化为一个long 型的数

unsigned short int 和 unsigned int 或 unsigned short 有啥区别?