牛骨文教育服务平台(让学习变的简单)
博文笔记

c++ unsigned和int类型转换及运算

创建时间:2017-02-08 投稿人: 浏览次数:3122

一、规则总结

1. 在c++中,如果赋值给无符号类型一个超过它表示范围的值(如负数),结果是初始值对无符号类型表示数值最大值取模后的余数。

2. 在c++中,如果表达式中同时有无符号类型和有符号类型,会默认将有符号类型转换为无符号类型进行运算,运算结果也是无符号类型。

二、以int和unsigned为例

1. 如果赋值给unsigned一个负数值,结果是什么?结果是将该负数对unsigned表示数最大值取模后的余数。

(1)unsigned表示数最大值

在大部分编译器中该类型占4个字节,则最大值是2的32次方,为4294967296。

(2)负数的取模运算

负数的取模运算和数学中的取余运算不同,区别主要体现在:取模运算商是向负的无穷大取值,而取余运算商是向0取值。举例说明:如-3对2取余商为-1,但-3对2取模商则是-2。

(3)赋值给unsigned一个负数值时实际得到的结果

                         

上述程序的输出结果是:


结果是怎么算出来的呢?

u=-1,-1除以4294967296,商是-1,而取模后的余数是4294967296-(-1*-1)=4294967295

u=-20,-20除以4294967296,商是-20,取模后的余数是4294967296-20=4294967276

u=-4294967296(这是unsigned能表示的负数的极限),商是-1(除不尽的需要向负无穷取值,能除尽就不用了),取模后的余数是4294967296-4294967296=0

2. 如果表达式中同时有unsigned和int,计算结果是什么?结果是将int转换为unsigned后再计算,结果也按照unsigned来转换


上述程序的输出结果为:


结果是怎么算出来的呢?

u1-u2=10-42=-32,u1和u2都是unsigned,结果也应是unsigned,-32超过了unsigned的表示范围,需要转换。按照上一小节中的转换方式,转换结果为4294967264

i1-u1=11-10=1,结果为unsigned的1。

u1-i1=10-11=-1,u1是无符号数,i1首先转换为无符号数为11,计算结果为-1,超出了unsigned范围,转换后为4294967295。



i=-1,转换为unsigned后4294967295,所以i-u=4294967295-10=4294967285


三、结论

切勿混用带符号类型和无符号类型!!!


补充:

在c++正常运算中,取模和取余是一样的,即使有负数也是一样的。(-m)/n=m/(-n)=-(m/n);m%(-n)=m%n;(-m)%n=-(m%n)。

但是由负数导致溢出时属于特殊情况,需要按照前面章节所述计算。

我们不需要关心溢出时结果是如何计算出来的,只需要避免溢出的发生。因为溢出后,结果总是不在我们控制中的。

声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。