int 变量不能存储大值
int variable is not able to store large values
#include <iostream>
int main()
{
int a = 999999999999999999;
std::cout << a << std::endl;
std::cout << 999999999999999999 << std::endl;
return 0;
}
以上程序的输出是-1486618625
和999999999999999999
。
在两个 cout
中我们给出相同的数字,为什么输出不同?
也long long int a=999999999999999
和int a=9999999999999999ll
一样吗?
在第一种情况下,您将值分配给一个 int,这对于最大值为 2147483647 的整数来说太大了,请查看此 link 了解更多信息 C++ Data Types
在第二种情况下,cout 将打印您提供的任何值。
将常数 999999999999999999 赋给一个 int 变量 (a) 会导致截断并更改值。但是,如果您将其声明为 long long a,则不会被截断,并且它会在任何具有 64 位的 long long[=14= 的平台上正确显示](即 Windows VC++)。
首先,您将 a 声明为 int
类型的变量。 int
类型的最大值为 2147483647,因此无论高于它的值都会被转换。所以你的 long 值被转换和存储,这就是打印的内容。但是当你直接给它没有任何值时,它可以是任何数据类型。这里的数据类型是 long long int
(64 位 int)。因此,如果您的编译器 OS 和硬件支持 64 位整数,那么它将被打印出来。如果您将第一个声明为 long long int
,则第一个也会正确打印。 long long int
的最大值是 92233703685477807 几乎足以存储 20!(20 的阶乘)。
当您将整数文字 999999999999999999
分配给 int a
时,如果 int
类型不能表示该数字,它可能会被截断。可以存储在 int
中的最大值是 std::numeric_limits<int>::max()
并且取决于您正在编译的平台(但必须至少为 32767)。你的编译器应该警告你这样的截断赋值:
$ g++ -std=c++11 -Wall -Wextra 32689548.cpp -o 32689548
32689548.cpp: In function ‘int main()’:
32689548.cpp:5:13: warning: overflow in implicit constant conversion [-Woverflow]
int a = 999999999999999999;
^
要回答您的问题,“[是] long long int a=999999999999999
与 int a=9999999999999999ll
相同” - 为什么不自己测试一下呢?像这样,也许:
#include <iostream>
int main()
{
long long int a = 999999999999999999;
int b = 999999999999999999ll;
std::cout << a << std::endl;
std::cout << b << std::endl;
std::cout << (a==b) << std::endl;
return 0;
}
$ g++ -std=c++11 -Wall -Wextra 32689548.cpp -o 32689548
32689548.cpp: In function ‘int main()’:
32689548.cpp:6:13: warning: overflow in implicit constant conversion [-Woverflow]
int b = 999999999999999999ll;
^
$ ./32689548
999999999999999999
-1486618625
0
在这里我们看到将 long long
分配给 int b
会导致相同的截断(正如 GCC 警告我们的那样)。但是,如果我们将 int b
更改为 auto b
,那么我们将不会收到任何警告和真正的比较:
999999999999999999
999999999999999999
1
有关信息,我在具有
的系统上构建并 运行 以上内容
std::numeric_limits<int>::max() = 2147483647
std::numeric_limits<long long int>::max() = 9223372036854775807
变量a定义为有符号整数数据类型- 4字节,有符号整数取值范围为[-2^31, 2^31]。为了便于理解,数据类型的值存储为圆圈,使得最小值紧挨着最大值[..,max-1, max, min, min+1...]。这意味着(最大值+ 1)的值是最小值。
当你作为int a=999999999999999
赋值时,因为这个值超过了有符号整数数据类型的范围值,整数范围值中的一个有效值被赋给变量a.
行语句cout<<a<<std::endl;
本质上是std运算符的重载basic_ostream<charT,traits>& operator<<(int n)
——打印出一个带符号的整数值。
行语句cout<<999999999999999999;
重载basic_ostream<charT,traits>& operator<<(long n)
,long数据类型为8字节数据类型,取值范围包含打印值'99..99',所以值为'99..99 ' 毫无疑问地打印出来。
尝试将var a定义为long数据类型long a = 999999999999999999
,打印出来就成功了。
#include <iostream>
int main()
{
int a = 999999999999999999;
std::cout << a << std::endl;
std::cout << 999999999999999999 << std::endl;
return 0;
}
以上程序的输出是-1486618625
和999999999999999999
。
在两个 cout
中我们给出相同的数字,为什么输出不同?
也long long int a=999999999999999
和int a=9999999999999999ll
一样吗?
在第一种情况下,您将值分配给一个 int,这对于最大值为 2147483647 的整数来说太大了,请查看此 link 了解更多信息 C++ Data Types
在第二种情况下,cout 将打印您提供的任何值。
将常数 999999999999999999 赋给一个 int 变量 (a) 会导致截断并更改值。但是,如果您将其声明为 long long a,则不会被截断,并且它会在任何具有 64 位的 long long[=14= 的平台上正确显示](即 Windows VC++)。
首先,您将 a 声明为 int
类型的变量。 int
类型的最大值为 2147483647,因此无论高于它的值都会被转换。所以你的 long 值被转换和存储,这就是打印的内容。但是当你直接给它没有任何值时,它可以是任何数据类型。这里的数据类型是 long long int
(64 位 int)。因此,如果您的编译器 OS 和硬件支持 64 位整数,那么它将被打印出来。如果您将第一个声明为 long long int
,则第一个也会正确打印。 long long int
的最大值是 92233703685477807 几乎足以存储 20!(20 的阶乘)。
当您将整数文字 999999999999999999
分配给 int a
时,如果 int
类型不能表示该数字,它可能会被截断。可以存储在 int
中的最大值是 std::numeric_limits<int>::max()
并且取决于您正在编译的平台(但必须至少为 32767)。你的编译器应该警告你这样的截断赋值:
$ g++ -std=c++11 -Wall -Wextra 32689548.cpp -o 32689548
32689548.cpp: In function ‘int main()’:
32689548.cpp:5:13: warning: overflow in implicit constant conversion [-Woverflow]
int a = 999999999999999999;
^
要回答您的问题,“[是] long long int a=999999999999999
与 int a=9999999999999999ll
相同” - 为什么不自己测试一下呢?像这样,也许:
#include <iostream>
int main()
{
long long int a = 999999999999999999;
int b = 999999999999999999ll;
std::cout << a << std::endl;
std::cout << b << std::endl;
std::cout << (a==b) << std::endl;
return 0;
}
$ g++ -std=c++11 -Wall -Wextra 32689548.cpp -o 32689548
32689548.cpp: In function ‘int main()’:
32689548.cpp:6:13: warning: overflow in implicit constant conversion [-Woverflow]
int b = 999999999999999999ll;
^
$ ./32689548
999999999999999999
-1486618625
0
在这里我们看到将 long long
分配给 int b
会导致相同的截断(正如 GCC 警告我们的那样)。但是,如果我们将 int b
更改为 auto b
,那么我们将不会收到任何警告和真正的比较:
999999999999999999
999999999999999999
1
有关信息,我在具有
的系统上构建并 运行 以上内容std::numeric_limits<int>::max() = 2147483647
std::numeric_limits<long long int>::max() = 9223372036854775807
变量a定义为有符号整数数据类型- 4字节,有符号整数取值范围为[-2^31, 2^31]。为了便于理解,数据类型的值存储为圆圈,使得最小值紧挨着最大值[..,max-1, max, min, min+1...]。这意味着(最大值+ 1)的值是最小值。
当你作为int a=999999999999999
赋值时,因为这个值超过了有符号整数数据类型的范围值,整数范围值中的一个有效值被赋给变量a.
行语句cout<<a<<std::endl;
本质上是std运算符的重载basic_ostream<charT,traits>& operator<<(int n)
——打印出一个带符号的整数值。
行语句cout<<999999999999999999;
重载basic_ostream<charT,traits>& operator<<(long n)
,long数据类型为8字节数据类型,取值范围包含打印值'99..99',所以值为'99..99 ' 毫无疑问地打印出来。
尝试将var a定义为long数据类型long a = 999999999999999999
,打印出来就成功了。