鱼C论坛

 找回密码
 立即注册
查看: 2313|回复: 11

[已解决]取值超出范围后是怎么算的?

[复制链接]
发表于 2022-7-26 16:13:59 | 显示全部楼层 |阅读模式
6鱼币
为什么a的值是65535,我记得小甲鱼讲过这个,但是我给忘了,现在不知道要去哪里翻那个了

#include <stdio.h>
int main(void)
{
  unsigned short a = -1;
  printf("%u", a);
  return 0;
}

最佳答案

查看完整内容

https://fishc.com.cn/thread-67124-1-1.html
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-7-26 16:14:00 | 显示全部楼层    本楼为最佳答案   
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-7-26 16:20:47 | 显示全部楼层
-2^15~2^15-1
为啥减一,因为有个0
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-7-26 16:24:53 | 显示全部楼层
jhq999 发表于 2022-7-26 16:20
-2^15~2^15-1
为啥减一,因为有个0

我没懂,什么叫因为有个0
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-7-26 16:30:32 | 显示全部楼层
本帖最后由 临时号 于 2022-7-27 14:09 编辑
1613551 发表于 2022-7-26 16:24
我没懂,什么叫因为有个0


这个代码发生了溢出
unsigned short的范围是0-65535,而你赋值了-1,因此发生了溢出,所以结果是65535
这种溢出的代码没有价值
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-7-26 16:39:32 | 显示全部楼层
1613551 发表于 2022-7-26 16:24
我没懂,什么叫因为有个0

可表示的负整数2^15个,正整数2^15-1个, 和1个0,一共2^16个
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-7-26 17:30:40 | 显示全部楼层
临时号 发表于 2022-7-26 16:30
这个代码发生了溢出
unsigned short的范围是0-65536,而你赋值了-1,因此发生了溢出,所以结果是65535
这 ...

很难认同“没有价值”这一观点。
首先关于这种类型转换,来看看标准中是如何规定的:
6.3.1.3 Signed and unsigned integers
1   When a value with integer type is converted to another integer type other than _Bool, if the value can be represented by the new type, it is unchanged.
2   Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.
3   Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.

* The rules describe arithmetic on the mathematical value, not the value of a given type of expression.

简单来说,当一个整数类型的值被转换到一个不为 _Bool 的整数类型时,如果该值在数值上可以由目标类型表示,则转换后值不变;否则(若目标类型无法表示原数值)如果目标类型为无符号类型,则反复将原数值加或减 ( 目标类型可以表示的最大数值加 1 ) 直到结果可以被目标类型表示,此时得到的结果为转换后的值;否则若目标类型有符号且无法表示原数值,标准不规定应产生何种效果,由具体实现自行决定。
综上所述,此处将数值 -1 转换到无符号类型 unsigned short 中,显然无法直接表示此数值,则将此数值反复加上 ( unsigned short 可以表示的最大数值加 1 ) 即 65536 直到结果可被 unsigned short 表示,即得到转换结果 65535 。
这种行为是标准明确定义的,因此可以通过向任意(非 _Bool 的)无符号类型赋值 -1 来将其赋值为其类型能够表示的最大值,而无需关心这种类型具体的有效位宽等信息。这以及类似的方法在编写特定用途的代码时很有帮助。

点评

我很赞同!: 5.0
我很赞同!: 5
  发表于 2023-6-1 20:43

评分

参与人数 1鱼币 +5 收起 理由
1613551 + 5

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-7-26 17:37:50 | 显示全部楼层
dolly_yos2 发表于 2022-7-26 17:30
很难认同“没有价值”这一观点。
首先关于这种类型转换,来看看标准中是如何规定的:

受教
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-7-26 18:12:34 | 显示全部楼层
-1在计算机中用
1 111 1111 1111 1111 Bin补
表示,第一个1表示负数
unsigned short会将其以
(0) 1111 1111 1111 1111 Bin补
处理,第一个0是逻辑上的,并不存在于内存中
所以就是65535了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-7-27 13:57:34 | 显示全部楼层
临时号 发表于 2022-7-26 16:30
这个代码发生了溢出
unsigned short的范围是0-65536,而你赋值了-1,因此发生了溢出,所以结果是65535
这 ...

啊?unsigned short的取值范围不是0~65535吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-7-27 14:09:37 | 显示全部楼层
1613551 发表于 2022-7-27 13:57
啊?unsigned short的取值范围不是0~65535吗?

不好意思,打错了,不仔细看还真看不出来
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-6 08:36

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表