与int字段.我在C#中发现错误了吗? [英] With the int field. Did I find a bug in C#?

查看:59
本文介绍了与int字段.我在C#中发现错误了吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在SQL中,您执行:

In SQL, you execute:

DECLARE @i int=1024*1024*1024
SET @i = @i + @i


您得到:


you get:

Msg 8115, Level 16, State 2, Line 2
Arithmetic overflow error converting expression to data type int.



SET @i = @i-1 + @i
可以正常工作,@ i变为2147483647.如果在原始文件中的"int ="之后插入减号(-),则可以正常工作,并且@ i = -2147483648.请注意,我没有为此抱怨,我知道溢出消息是30多年前的您的朋友. 30年前,当我学习FORTRAN时,它做到了.我以为我使用的每种编程语言都可以做到这一点.由于我确定没有编写类似的错误,因此我以为自己受到算术溢出错误的保护.

输入我编写的C#应用​​程序,我要在其中测试其极限.我发现它会因堆栈溢出跟踪错误而崩溃.我在调试模式下运行,所以我查看了数字.什么?我使用的int计数器之一接近负20亿.我只添加正数,这怎么可能???我发现编译后的版本不会因堆栈溢出而崩溃,并且int计数器还低一些.我开始增加抗数,增加负载,每次工作时,计数器得到的负数越来越小.在打击之前,计数器下降到大约-40K记录.将计数器从int更改为uint只能使4G最大值减少约40K记录.

我认为这是一个错误.我在C#中发现错误了吗?

顺便说一句,稍后我将从1开始的值和1073741824乘以2的值加倍了-2147483648.也许我应该将其加倍,看看我是否得到0?

PS我放在try/catch块中,堆栈溢出将无法捕获.这对我来说很有意义(令人失望),我不认为这是一个错误.



SET @i = @i - 1 + @i
works just fine, @i becomes 2147483647. If you insert a minus (-) just after "int=" in the original, it works fine, and @i=-2147483648. I''m not complaining about that, mind you, I learned the overflow message was your friend over 30 years ago. When I learned FORTRAN 30+ years ago, it did that. I thought every programming language I used would do that. Since I made sure I didn''t code an error like that, I just thought I was protected by the arithmetic overflow error.

Enter a C# application I wrote, where I wanted to test it''s limits. I got it to blow up with a Stack overflow trace error. I was running in debug mode, so I reviewed the numbers. What the??? One of the int counters I was using was close to minus 2 billion. I''m only adding positive numbers, how can that happen??? I find out the compiled version doesn''t blow up with a Stack Overflow and the int counter is a bit lower still. I start upping the anti, increasing the load and each time, it works, the counter gets a smaller and smaller negative number. Just before it blows the counter gets down to around -40K records. Changing the counter from int to uint the counter is just shy of the 4G maximum value by about 40K records.

I think that''s a bug. Did I find a bug in C#?

By the way, later I doubled values starting from 1 and 1073741824 multiplied by 2 is -2147483648. Maybe I should have doubled that to see if I got 0?

PS I put in a try/catch block and the stack overflow won''t catch. That makes sense to me (It is disappointing) and I don''t think that is a bug.

推荐答案

KP Lee 写道:

我正在使用的一个int计数器接近负20亿.我只添加正数,那怎么可能??

One of the int counters I was using was close to minus 2 billion. I''m only adding positive numbers, how can that happen???



好,这个就足够了.抱歉,您已有30年的经验:也许您了解了一些FORTRAN(一开始我也使用了它,直到我意识到这不值得花心思),但是您并没有了解一些非常基本的计算基础知识.当然,加到整数必须最终会得到负数.

您所说的与堆栈溢出无关.如果您想知道堆栈和堆栈溢出的工作方式,则应该单独解决.这是整数溢出.

当然,您没有找到C#中的错误,但从您的理解中确实找到了一个错误.没什么大不了的:只需修复它即可.您可以在此处找到完整而全面的说明:

http://en.wikipedia.org/wiki/Two%27s_complement .

关键是:您正在使用一个系统,该系统使用两个补码表示来解释有符号整数.这种表示非常实用:它允许CPU在不使用有关整数类型(带符号或无符号或不同类型的操作数)的信息的情况下执行算术运算.另外,它还排除了-0和+0作为不同的对象.

有关该主题的更多背景,请参阅:
http://en.wikipedia.org/wiki/Signed_number_representations 以及本文中的Web链接.



要使计算对整数溢出敏感,请在checked模式下执行它们:



OK, this one is enough. Sorry for your 30 years of experience: perhaps you learned some FORTRAN (I used it, too, in the very beginning, before I realized it does not worth the effort), but you did not get to understanding some of very basic fundamentals of computing. Of course, adding to the integer number must end up having a negative number.

What you are talking about have nothing to do with stack overflow. If you want to know how stack and stack overflow works, it should be a separate question. This is integer overflow.

Of course you did not find a bug in C#, but you did find one in your understanding. Not a big deal: just fix it. You will find complete and comprehensive explanation here:

http://en.wikipedia.org/wiki/Two%27s_complement.

The thing is: you are using a system where signed integers are interpreted using two''s complement representation. This representation is very practical: it allows for CPU to perform arithmetic operations using no information about a type of integer number, signed or unsigned or operands of different types. Also, it exclude the presence of -0 and +0 as different objects.

For more background on the topic, please see:
http://en.wikipedia.org/wiki/Signed_number_representations as well as Web links found in this article.



To get calculation sensitive to integer overflow do them under checked mode:

checked {
    int myInt = 1 << 30; //positive 2^30, 2^31 is already negative as 1 << 31 is a sign bit

    //attempt to get 1 << 32 == 0x80000000 will overflow to -2147483648
    myInt = myInt * 2; //but exception will be thrown here only under "checked"
}    



最大32位int(int)0x7fffffff,不是很明显吗?

[END EDIT]

祝你好运,

—SA



Maximum 32-bit int is (int)0x7fffffff, isn''t that obvious?

[END EDIT]

Good luck,

—SA


在SQL方面不确定;但是C#按照其标准可以正常工作.

由于您是高级程序员,因此让我简要介绍一下C#int数据类型.

每种值类型都是从System.Object< -System.Value"派生的对象.在C#中声明"int"时,它是一个表示System.Int32类型的宏.
Int32是一个不可变的值类型,它表示带符号整数,其值范围从负2147483648(由Int32.MinValue常数表示)到正2147483483647(由Int32.MaxValue常数表示). .NET Framework还支持无符号的32位整数值类型UInt32,它表示范围从0到4,294,967,295的值.
根据算术溢出,内部存储的位会被卡住!
Not sure on SQL side; but C# works fine as per its standards.

Since, you are a senior programmer, let me give a brief view on the C# int data type.

Every value type is an object derived from System.Object<-System.Value. When you declare ''int'' in C#, it''s a macro representing System.Int32 type.

Int32 is an immutable value type that represents signed integers with values that range from negative 2,147,483,648 (which is represented by the Int32.MinValue constant) through positive 2,147,483,647 (which is represented by the Int32.MaxValue constant). .NET Framework also supports an unsigned 32-bit integer value type, UInt32, which represents values that range from 0 to 4,294,967,295.

As per arithmetic overflow, the internally stored bits are jammed around!


int是带符号的类型,因此您已经添加了足够的内容来设置MSB,并将其标记为-ve数字

我认为您的堆栈错误可能是红色鲱鱼
the int is signed type, so you''ve added enough to set the MSB, and flag it as a -ve number

I think your stack fault may be a red herring


这篇关于与int字段.我在C#中发现错误了吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆