0 c++ integer g++ visual-c++ long-integer
我正在玩一些c ++代码,发现如果我用4294967295(它的最大允许值)开始一个unsigned long并添加让我们说6我必须得到5,它确实!但是以下添加操作,而mod 255没有给出正确的答案.为什么会这样,以及如何避免?
Plataforms经过测试:
Windows 7,Visual Studio c ++:工作正常;
CentOS版本6.6(最终版),g ++:给出错误的答案;
请参阅下面的代码注释:
#include <stdio.h>
int main(int argc, char *argv[]) {
unsigned long s1=4294967295;
unsigned long vp=245;
unsigned long a;
unsigned long b;
unsigned long result;
/* s1 is 4294967295 + 6 wich is 5 */
s1+=6;
a=s1;
b=255*vp*s1;
result = (a + b) % 255;
printf("s1=%u , a=%u , b=%u , (a+b)=%u , (a+b)%255= %u\n", s1, a, b, a + b, result);
/* s1 is a static value 5 */
s1=5;
a=s1;
b=255*vp*s1;
result = (a + b) % 255;
printf("s1=%u , a=%u , b=%u , (a+b)=%u , (a+b)%255= %u\n", s1, a, b, a + b, result);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
注意:如果我使用Visual Studio编译代码,我会得到正确的答案.
s1=5 , a=5 , b=312375 , (a+b)=312380 , (a+b)%255= 5
s1=5 , a=5 , b=312375 , (a+b)=312380 , (a+b)%255= 5
Run Code Online (Sandbox Code Playgroud)
但是,如果我使用gcc版本4.4.7 20120313(Red Hat 4.4.7-11)(GCC)编译,我得到:
s1=5 , a=5 , b=312375 , (a+b)=312380 , (a+b)%255= 6
s1=5 , a=5 , b=312375 , (a+b)=312380 , (a+b)%255= 5
Run Code Online (Sandbox Code Playgroud)
如何在g ++中避免它?
如果我用4294967295(他的最大允许值)开始一个无符号长整数
4294967295只是unsigned longif unsigned long是32位类型的最大值.在Windows上就是这种情况,包括32位和64位.在Linux上,unsigned long在32位平台上是32位类型,在64位平台上是64位类型.C++标准没有规定类型的特定大小,它只表示unsigned long必须至少为32位,因此Windows和Linux都是正确的.
如果你想有一个保证的32位类型,使用uint32_t的<cstdint>(如果可用).这是该语言的最新成员,我不知道您的Visual Studio版本是否还有它; 如果没有,请参阅'uint32_t'标识符未找到错误.
另外,请注意您用于打印值的代码中存在错误.它碰巧在您尝试过的两个平台上没有崩溃,但它会在GCC中截断结果.要打印出来unsigned long,你需要使用说明%lu符,而不是%u.要打印出百分比字符,您需要加倍%.
printf("s1=%lu , a=%lu , b=%lu , (a+b)=%lu , (a+b)%%255= %lu\n", s1, a, b, a + b, result);
Run Code Online (Sandbox Code Playgroud)
或者,由于您使用的是C++,因此请使用自己的打印机制.
#include <iostream>
…
std::cout << "s1=" << s1
<< ", a=" << a
<< ", b=" << b
<< ", (a+b)=" << (a+b)
<< ", (a+b)%255=" << result;
Run Code Online (Sandbox Code Playgroud)
在unsigned long64位类型的平台上,s1第一轮的值为4294967301.值为b268328082129975.如果使用正确的打印说明符,您将看到这些值.