gpt4 book ai didi

c++ - 大的负整数文字

转载 作者:可可西里 更新时间:2023-11-01 15:45:54 26 4
gpt4 key购买 nike

在 Visual Studio 2010 上执行以下程序

#include <iostream>
using std::cout;

int main()
{
cout << -2147483646 << '\n';
cout << -2147483647 << '\n';
cout << -2147483648 << '\n'; // numeric_limits<int>::min()
cout << -2147483649 << '\n';
cout << -2147483650 << '\n';
cout << "..." << '\n';
cout << -4294967293 << '\n';
cout << -4294967294 << '\n';
cout << -4294967295 << '\n'; // -numeric_limits<unsigned int>::max()
cout << -4294967296 << '\n';
cout << -4294967297 << '\n';
}

生成以下输出

-2147483646
-2147483647
2147483648
2147483647
2147483646
...
3
2
1
-4294967296
-4294967297

这是怎么回事?

这是标准行为还是 Visual Studio 错误?

编辑:正如一些人所指出的,没有负整数文字这样的东西。有关详细信息,请参阅下面 Keith Thompson 的出色回答。

最佳答案

-2147483648,例如,不是整型字面量;它是由应用于文字 2147483648 的一元 - 运算符组成的表达式。

在新的 C++ 2011 标准之前,C++ 不要求存在任何大于 32 位的类型(C++2011 添加了 long long),所以文字 2147483648 不可移植。

十进制整数字面值属于以下类型中的第一个,它的值适合:

int
long int
long long int (new in C++ 2011)

请注意,在标准 C++ 中,它绝不是无符号类型。在 1998 和 2003 版本的 C 标准(没有 long long int)中,太大而不适合 long int 的十进制整数文字会导致 undefined行为。在 C++2011 中,如果十进制整数字面量不适合 long long int,则程序“格式错误”。

但是 gcc(至少从 4.6.1 版开始,我拥有的最新版本)没有实现 C++2011 语义。不适合 32 位长的文字 2147483648 被视为 unsigned long,至少在我的 32 位系统上是这样。 (这对 C++98 或 C++2003 没问题;行为是未定义的,因此编译器可以做任何它喜欢的事情。)

所以给定一个典型的 32 位 2 的补码 int 类型,这个:

cout << -2147483647 << '\n';

获取 int2147483647,取反,并打印结果,这与您期望的数学结果相匹配。但是这个:

cout << -2147483648 << '\n';

(使用 gcc 4.6.1 编译时)采用 longunsigned long2147483648,将其取反 作为无符号int,产生 2147483648,并打印它。

正如其他人所提到的,您可以使用后缀来强制使用特定类型。

这是一个小程序,您可以用它来展示编译器如何处理文字:

#include <iostream>
#include <climits>

const char *type_of(int) { return "int"; }
const char *type_of(unsigned int) { return "unsigned int"; }
const char *type_of(long) { return "long"; }
const char *type_of(unsigned long) { return "unsigned long"; }
const char *type_of(long long) { return "long long"; }
const char *type_of(unsigned long long) { return "unsigned long long"; }

int main()
{
std::cout << "int: " << INT_MIN << " .. " << INT_MAX << "\n";
std::cout << "long: " << LONG_MIN << " .. " << LONG_MAX << "\n";
std::cout << "long long: " << LLONG_MIN << " .. " << LLONG_MAX << "\n";

std::cout << "2147483647 is of type " << type_of(2147483647) << "\n";
std::cout << "2147483648 is of type " << type_of(2147483648) << "\n";
std::cout << "-2147483647 is of type " << type_of(-2147483647) << "\n";
std::cout << "-2147483648 is of type " << type_of(-2147483648) << "\n";
}

当我编译它时,我收到一些警告:

lits.cpp:18:5: warning: this decimal constant is unsigned only in ISO C90
lits.cpp:20:5: warning: this decimal constant is unsigned only in ISO C90

和以下输出,即使使用 gcc -std=c++0x:

int: -2147483648 .. 2147483647
long: -2147483648 .. 2147483647
long long: -9223372036854775808 .. 9223372036854775807
2147483647 is of type int
2147483648 is of type unsigned long
-2147483647 is of type int
-2147483648 is of type unsigned long

我在 VS2010 上得到了相同的输出,至少在默认设置下是这样。

关于c++ - 大的负整数文字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8511598/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com