前置客观常识
int 2字节,65536;
long 4字节,2^31-1,(2,147,483,647),约21亿;
unsigned long 4字节,2^32-1,约42亿;
long long 8字节,2^63-1,(9,223,372,036,854,775,807),约9e18;
PS: C++11中才正式引入long long,古老编译器很容易发生未知问题
输出时
%d 范围同long,属于有符号4字节,上限21亿左右;
%u 范围同unsigned long,无符号4字节,上限42亿左右;
%ld 不常见,应该算是4字节的有符号
%lld 据说对应long long int ,8字节有符号,上限约9e18。
测试:
角谷猜想示例
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cmath>
using namespace std;
//1.角谷猜想
//奇数*3+1,偶数/2,最后得到1,返回End
int main(){
//测试点输入 159487
long long n, x;
//中间步骤会算到170亿
//longlongint 8字节可达到9e18
scanf("%lld", &n);
while (n>0){
if (n == 1) {
printf("End");
break;
}
else if (n % 2 == 1){
x = n; //储存n
n = n * 3 + 1;
printf("%lld*3+1=%lld\n", x, n);
//测试点输入159487
//直接用%d输出时, 中间算到 755111231*3+1=2265333694,会输出一个负数 ,因为超过了有符号的4字节上限21亿
//改成%u输出,在2265333694输出没有问题
//但是算到1699000271*3+1=5097000814,会输出一个 802033518,不正确。因为超过了无符号的4字节上限42亿。
//改成%ld后同样会出现负数,显然ld也对应一个4字节的上限。但是%ld提交OJ是成功的!
//改成%lld后本地正常,OJ也通过
//使用cout没有问题
//cout << x << "*3+1=" << n << endl;
}
else if (n % 2 == 0){
x = n;
n = n / 2;
printf("%lld/2=%lld\n", x, n);
//cout<<x<<"/2="<<n<<endl;
}
}
system("pause");
return 0;
}
//%lld对应long long int,显然能够输出172亿
//研究%ld的表现状况,系统环境win10x64
//提交OJ显示Accepted。即在OJ的系统内,使用%ld可以成功输出17202377752,即172亿的数字
//devc++中通过编译,但是中间会出现负数
//VS2013中输出等号后面总是0,中间又会出现负数。不知道为什么
//如果出现负数应该不满足while(n>0)直接停止才对啊
结论:
1.%ld未知原因,在本地与OJ上表现性能不同;
2.出于安全考虑,建议%ld对应long(<21亿),%lld对应long long(<9e18) ;
3.建议在遇到超大数时,使用cout以节约脑细胞;