C++;无符号长不';t在4294967295之后缠绕 我玩了一些C++代码,发现如果我用4294967295(它的最大允许值)启动一个未签名的long,加上我们说6,我必须得到5,它确实是!但是下面的加法运算和mod 255并没有给出正确答案。为什么会发生这种情况,以及如何避免这种情况

C++;无符号长不';t在4294967295之后缠绕 我玩了一些C++代码,发现如果我用4294967295(它的最大允许值)启动一个未签名的long,加上我们说6,我必须得到5,它确实是!但是下面的加法运算和mod 255并没有给出正确答案。为什么会发生这种情况,以及如何避免这种情况,c++,visual-c++,integer,g++,long-integer,C++,Visual C++,Integer,G++,Long Integer,已测试平台形状: Windows 7,VisualStudioC++:工作精细;br> 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; unsig

已测试平台形状:
Windows 7,VisualStudioC++:工作精细;br> 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;
}
但是,如果我使用gcc版本4.4.7 20120313(Red Hat 4.4.7-11)(gcc)编译,我会得到:


在g++中如何避免这种情况?

您使用的是64位系统吗?因为
long
在GCC中通常是64位,而在visualstudio编译器中仍然是32位,这将解释为什么它不适用于GCC而适用于VS

要获取某个类型的最大值,请使用获取它,例如

unsigned long s1 = std::numeric_limits<unsigned long>::max();
unsigned long s1=std::numeric_limits::max();
如果我以4294967295(他的最大允许值)开始一个无符号长

如果
unsigned long
为32位类型,则4294967295仅为
unsigned long
的最大值。Windows上的情况就是如此,包括32位和64位。在Linux上,
unsigned long
在32位平台上是32位类型,但在64位平台上是64位类型。C++标准不指定特定的大小,它只表示<代码>未签名的长< /C>至少32位,因此Windows和Linux都是正确的。 如果您想要保证32位类型,请使用
中的
uint32\t
(如果可用)。这是该语言的最新添加,我不知道您的Visual Studio版本是否有它;如果没有,请参阅

此外,请注意,用于打印值的代码中存在错误。它碰巧没有在您尝试的两个平台上崩溃,但它截断了GCC中的结果。要打印无符号长字符,需要使用
%lu
说明符,而不是
%u
。要打印百分比字符,需要将
%
加倍

printf("s1=%lu , a=%lu , b=%lu , (a+b)=%lu , (a+b)%%255= %lu\n", s1, a, b, a + b, result);

或者替代地,因为你使用C++,使用它自己的打印机制。

#include <iostream>
…
    std::cout << "s1=" << s1
              << ", a=" << a
              << ", b=" << b
              << ", (a+b)=" << (a+b)
              << ", (a+b)%255=" << result;
#包括
…

std::cout和它打印5和6而不是一个大数字的事实可能是因为它们在
printf()
.Ops!中使用
%u
而不是
%lu
!。我懂了。我将类型更改为unsigned int,它是32位。现在一切正常。一些编译器指令待办事项,谢谢。“如果我以4294967295(他的最大允许值)开始一个无符号long”,你在哪里读到的?uint32可以找到#include有uint32,这不是新添加的。所以它比@user4983898要好,因为它从C99开始就在C中,但Windows在实现C99方面远远落后。它只是最近才正式在C++中正式制作的。
printf("s1=%lu , a=%lu , b=%lu , (a+b)=%lu , (a+b)%%255= %lu\n", s1, a, b, a + b, result);
#include <iostream>
…
    std::cout << "s1=" << s1
              << ", a=" << a
              << ", b=" << b
              << ", (a+b)=" << (a+b)
              << ", (a+b)%255=" << result;