为什么这会导致长整型溢出

发布于 2024-12-10 00:39:38 字数 380 浏览 0 评论 0原文

我检查了文档, long= int64 的范围超过 900,000,000,000,000

这是我的代码:

int r = 99;
long test1 = r*r*r*r*r;

在运行时它给了我 919,965,907 而不是正确的 9,509,900,499。

另一个测试

long test2 = 99*99*99*99*99;

它拒绝编译,说整数溢出。

但如果我这样做,

long test3 = 10100200300;

效果很好。

I checked the document that long= int64 has range more than 900,000,000,000,000

Here is my code:

int r = 99;
long test1 = r*r*r*r*r;

at runtime it gives me 919,965,907 instead of the correct 9,509,900,499.

another test

long test2 = 99*99*99*99*99;

It refuses to compile, saying integer overflow.

But if i do this

long test3 = 10100200300;

This works fine.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

苦笑流年记忆 2024-12-17 00:39:38

问题在于文字“99”被视为 int。如果添加“L”,它会将其视为长整型。解决您的编译问题:

long test2 = 99L * 99L * 99L * 99L * 99L;

并解决由整数溢出引起的“不正确的结果”:

long r = 99;
long test1 = r * r * r * r * r;

关键点是“=”右侧的表达式在赋值给 之前计算 long r 已完成。

您可能还对其他文字后缀感兴趣:

Type    Suffix    Example
uint    U or u    100U
long    L or l    100L
ulong   UL or ul  100UL
float   F or f    123.45F
decimal M or m    123.45M

@m.edmonson,关于您关于为什么结果是 919965907 的问题。发生的情况是该值“包裹”在 int.MaxValue 周围。您可以通过一个小测试程序看到这一点:

int i = 99; // 99
i *= 99;    // 9801
i *= 99;    // 970299
i *= 99;    // 96059601
i *= 99;    // 919965907        should be 9509900499 but comes out to 919965907
            //                      which is (9509900499 % int.MaxValue)

long k = 9509900499 % int.MaxValue;

“环绕”是什么意思?当超过 int.MaxValue 1 时,该值将“返回”到 int.MinValue

int j = int.MaxValue;
j++;

bool isNowMinValue = (j == int.MinValue);   // true, the value has "wrapped around"

这有点简单化了;如果您搜索“整数溢出”,您会得到更好的解释。值得了解如何用 32 位表示整数(和其他数字类型):

http://en.wikipedia。 org/wiki/Signed_number_representations

The problem is that the literal "99" is being treated as an int. If you add "L" it will treat it as a long. To fix your compilation problem:

long test2 = 99L * 99L * 99L * 99L * 99L;

And to fix the "incorrect result" caused by integer overflow:

long r = 99;
long test1 = r * r * r * r * r;

The key point is that the expression to the right of the "=" is evaluated before the assignment to long r is done.

There are other literal suffixes you might be interested in:

Type    Suffix    Example
uint    U or u    100U
long    L or l    100L
ulong   UL or ul  100UL
float   F or f    123.45F
decimal M or m    123.45M

@m.edmonson, regarding your question about why it comes out to 919965907. What's happening, is that the value is "wrapping" around int.MaxValue. You can see this with a little test program:

int i = 99; // 99
i *= 99;    // 9801
i *= 99;    // 970299
i *= 99;    // 96059601
i *= 99;    // 919965907        should be 9509900499 but comes out to 919965907
            //                      which is (9509900499 % int.MaxValue)

long k = 9509900499 % int.MaxValue;

What is meant by "wrapping around"? When you exceed int.MaxValue by 1, the value "goes back" to int.MinValue.

int j = int.MaxValue;
j++;

bool isNowMinValue = (j == int.MinValue);   // true, the value has "wrapped around"

This is a bit simplistic; if you search for "integer overflow" you will get a better explanation. It's worth understanding how integers (and other numeric types) are represented with 32 bits:

http://en.wikipedia.org/wiki/Signed_number_representations

凉风有信 2024-12-17 00:39:38

它使用整数乘法:

long r = 99;
long test1 = r*r*r*r*r;

It's using integer multiplication :

long r = 99;
long test1 = r*r*r*r*r;
十级心震 2024-12-17 00:39:38

正如其他人所说,但是:

long test2 = 99L * 99 * 99 * 99 * 99;

这将为您提供正确的结果,并且周围有更少的 L :-)

发生这种情况是因为第一个 99L 是一个 long,所以所有乘法在long“字段”中完成,所有其他整数在乘法之前都被向上转换为long(显然,乘法总是在两个数字之间,并且是从左到右,所以就像(((99L * 99) * 99) * 99) * 99 并且每个“部分”结果都是 long 并导致下一个操作数转换为 long。)

As the other have said, but:

long test2 = 99L * 99 * 99 * 99 * 99;

This will give you the correct result with less L around :-)

This happens because the first 99L is a long, so all the multiplications are done in the long "field" and all the other integers are upcasted to long before the multiplication (clearly the multiplication is always between 2 numbers and it's from left to right, so it's like (((99L * 99) * 99) * 99) * 99 and each "partial" result is a long and causes the next operand to be converted to long.)

丑疤怪 2024-12-17 00:39:38

你的第二个测试失败了,因为每个 99 都是一个整数;将其替换为以下内容并编译。

long test2 = 99L * 99L * 99L * 99L * 99L;

有关详细信息,请参阅 MSDN 长文档

Your second test fails because each 99 is an integer; replace it with the following and it compiles.

long test2 = 99L * 99L * 99L * 99L * 99L;

See the MSDN Long Documentation for details.

魄砕の薆 2024-12-17 00:39:38

编译器将 99 视为整数,即使最终结果很长。

这会起作用。

long test2 = 99L*99L*99L*99L*99L;

The compiler is looking at 99 as integers, even though the final result will be long.

This will work.

long test2 = 99L*99L*99L*99L*99L;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文