从long long 谈类型转换

今天答题中遇到个经典的 long long 运行 异常的求助题。由此我们来引申到隐式转换需要主要的一些问题。

先把这题目拿来看看。
原题目:
计算1+2+3+·······+n (1<=n<=1,000,000,000)

将1,000,000,000作为下面两个程序的输入

#include
using namespace std;

int main(int argc, char *argv[]) {
long n; //问题在这里
long long sum=0;
cin>>n;
sum=(1+n)*n/2;
cout<<sum;
return 0;
}

结果是错的,出现的结果是 -243309312,想要得到的结果是500000000500000000。
什么原因呢?
首先说明下,long 类型 不会自动转换为long long 类型,long long 类型是C99标准增加的新的类型,不在隐式转换的范畴内。
所以当n为long 类型时 ,右侧数据计算出的结果还是以long类型存储,500000000500000000 对应的 0x06f05b59f17f6500,右边数据溢出被截取保留低4个字节,即0xf17f6500; 此时最高为为1,故为负数,赋值给longlong类型后,高4字节每位会被填充1,即sum = 0xfffffffff17f6500 . 对应的十进制数即为-243309312

那我们在贴上隐式转换的经典代码

int main(int argc, char *argv[]) {
	char a = 0x80;
	int b =0;
	short int ssi = 0x7fff;  //短整型有符号数最大值
	int si = ssi * ssi;    ///此处右侧计算会溢出吗
	long  n = 1000000000;
	long long ll = (1+n) * n /2;
	b = a * a ;
	cout << b<<endl;
	printf("a:%d,%d\n", b, a);
	cout << "si" << si << endl;
	cout << "ssi" << ssi << endl;
	cout << "long" << n << endl;
	cout << "Long long" << ll << endl;
	cout << "sizeof(shorte int)" << sizeof(short int) << endl;
	cout << "sizeof(int)" << sizeof(int) << endl;
	cout << "sizeof(long) :" << sizeof(long) << endl;
	cout << "sizeof(longlong)" << sizeof(long long) << endl;
	return 0;
}

此处和上例做了一个对比,其中整形 si = ssi * ssi; ssi 为有符号短整型最大值,右侧程式得到的结果肯定大于两个字节,但是si最终结果却为正值,和上例不一样的地方。这就涉及到隐式转换中的赋值转换。

赋值转换:
c语言中.如果赋值运算符两侧都是数值型数据或都是字符型数据,那么在赋值过程中会进行自动类型转换,转换的规则归纳如下。
(1)若将整型数据赋值给单精度或双精度的浮点型变量时,系统自动将整型数据转换为单精度或双精度数据(数值不变,但以浮点数形式存储到变量中)。
(2)若将单精度或双精度的浮点型数据赋值给整型变量时,系统自动将浮点型数据取整转换为整型(舍弃浮点型数的小数部分进行取整)。
(3)若将字符型数据赋值给整型变量时,由于宁符型数扔只占一个字节.而整型数据占两个字节,因系统将字符型数据放入整型变量的低八位中,整型变量的高八位则根据第八位决定在高八位补1或补0。
例如char a = 0x80;
int b = a;
b 的值等于0xffffff80。

还有一点隐式转换的地方,关系表达式中也会隐式转换。来一道经典的面试题。

unsigned int a = 10;
int b = -20;

(a + b > -6) ? puts("> -6") : puts("<= -6");   //<=-6
(a + b > 6) ? puts("> 6") : puts("<= 6");    //>6

输出结果为:
<= -6

6;
都是转换成无符号数后进行比较,所以结果这样。
最后我们上一张经典的隐式转换图作为本章的结束。
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值