有符号整数溢出:1111111111111111111 * 10 不能用“long long”类型表示
Posted
技术标签:
【中文标题】有符号整数溢出:1111111111111111111 * 10 不能用“long long”类型表示【英文标题】:signed integer overflow: 1111111111111111111 * 10 cannot be represented in type 'long long' 【发布时间】:2017-06-22 15:55:30 【问题描述】:int get_dnum(long long ccn,int di)
long long x=1;
for(int y=1;y<di;y++)
x=x*(long long)10;
return ccn%x;
x 是 long long。10 是 long long。这个错误是怎么发生的?
运行时错误:有符号整数溢出:1111111111111111111 * 10 不能用“long long”类型表示【问题讨论】:
您的意思可能是在 for 语句中增加y
,而不是 x
。
600 毫升水可装入一升瓶中。 500 毫升可装入 1 升瓶中。那600毫升和500毫升怎么装不下1升的瓶子?
long long
(默认情况下是有符号的)应该是(至少)64位长度,这意味着最大可表示数是(至少)+9,223,372,036,854,775,807(即2^63 -1)。您指定的数字 1,111,111,111,111,111,111 小于 9,223,372,036,854,775,807,因此适合签名的long long
。但是,您的数字乘以 10 超过了签名 long long
的最大值。如果您将 x
声明为 unsigned long long
类型,那么您指定的乘法应该可以工作。祝你好运。
谢谢。我想我现在明白了。
@BobJarvis 你愿意回答吗?听起来不错,即使不是震撼世界的 Q/A 对。
【参考方案1】:
long long
(默认情况下是带符号的)应该是(至少)64 位长度,这意味着最大可表示数是(至少)+9,223,372,036,854,775,807(即 2^63-1)。您指定的数字 1,111,111,111,111,111,111 小于 9,223,372,036,854,775,807,因此适合签名的long long
。但是,您的数字乘以 10 超过了 64 位签名 long long
的最大值。如果您将 x 声明为 unsigned long long
类型,那么您指定的乘法应该可以工作。
祝你好运。
【讨论】:
"但是,您的数字乘以 10 超过了 64 位有符号 long long 的最大值。"后面应该跟“.. 那是未定义的行为。”示例未定义的行为 是运行时错误。使用 unsigned long long 确实可以防止数学溢出,但即使它确实数学溢出,也不会有 undefined behavior 因为指定了 unsigned 溢出“包装”。 哈佛大学、麻省理工学院、达特茅斯学院、耶鲁大学和其他几所大学最近宣布了一个新的专业领域,该领域将结合计算机科学系和法学院的工作。这个新程序将培训个人了解 C 和 C++ 语言标准的许多不同形式的细节。该联合学位课程的既定目的是“……增加对这些重要语言的了解,并为有关它们的知情讨论、争论和仇杀提供更多机会”。新学位暂定称为 ll_c。以上是关于有符号整数溢出:1111111111111111111 * 10 不能用“long long”类型表示的主要内容,如果未能解决你的问题,请参考以下文章
运行时错误:有符号整数溢出:2147483647 + 1 不能以“int”类型表示
有符号整数溢出:999999999 * 10 不能用“int”类型表示错误