【问题标题】:C++ Visual Studio weired behaviour of signed integerC++ Visual Studio 有符号整数的奇怪行为
【发布时间】:2016-04-13 10:22:32
【问题描述】:

我的计算中有一些很长很长的边界常数。现在我有一个奇怪的行为,因为某些条件无效,因为数字被“误解” 第一个输出是我想要使用的数字....在输出中你可以看到 - 符号被删除了,所以我想到了一个下溢,但是当我添加一个 0,所以数字更高,输出是正确的......

我正在使用 Visual Studio 2012

cout<<-2147483648<<endl;
cout<<-2147483649<<endl;
cout<<-21474836480<<endl;
cout<<-21474836490<<endl;
cout<<-214748364800<<endl;
cout<<-214748364900<<endl;

如您所见,在前 2 行中 - 符号已删除

2147483648
2147483647
-21474836480
-21474836490
-214748364800
-214748364900

任何想法这里有什么问题?

【问题讨论】:

  • 您的示例甚至无法在 VS2012 中编译。对于这两行,它失败并显示以下错误消息:error C4146: unary minus operator applied to unsigned type, result still unsigned

标签: c++ visual-studio long-integer signed


【解决方案1】:

编译器警告不容忽视!

由于您没有为整型文字添加后缀,因此编译器使用 int 表示小于 INT_MAX 的值,使用 unsigned int 表示介于 INT_MAX 和 UINT_MAX 之间的值。假设一个 2 补码 32 位平台,INT_MAX 是 2147483647,所以 2147483648 和 2147483648 是无符号的,正如警告所说,对无符号类型应用减号仍然会给出正值。所以结果是溢出造成的。

正确的方法是用 L 为 long 和 LL 为long long 加后缀:

cout<<-2147483648LL<<endl;
cout<<-2147483649LL<<endl;
cout<<-21474836480LL<<endl;
cout<<-21474836490LL<<endl;
cout<<-214748364800LL<<endl;
cout<<-214748364900LL<<endl;

【讨论】:

    【解决方案2】:

    您应该仔细检查编译器提供给您的警告消息。如果您的代码没有产生警告,那么您应该提高编译器的警告生成级别。 MSVC 编译器上的这段代码会产生两个警告:

    警告 C4146:一元减号运算符应用于无符号类型,结果 还没有签名

    这基本上意味着,编译器将威胁前两个值作为unsigned int,然后将其应用于一元减号运算符。要解决这个问题,你应该隐式声明值类型:

    cout << -(long long)2147483649 << endl;
    

    【讨论】:

    • 非常感谢!我什至必须做 long long test=-(long long)2147483648
    • LL 后缀可能是要走的路(而不是演员表),如果您使用的是最近的编译器,您可以这样做:auto value = -214748364900LL;
    猜你喜欢
    • 1970-01-01
    • 2015-02-24
    • 2016-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-02
    • 2016-08-22
    • 1970-01-01
    相关资源
    最近更新 更多