.NET RT错误?从浮子到int的明确转换溢出,但没有例外

发布于 2025-02-08 16:52:19 字数 1207 浏览 0 评论 0原文

我偶然发现了一个有趣的行为,想问一下,是否有人可以解释为什么以下内容没有以.net语言抛出OverflowException(使用.NET 6签名

var f = (float)int.MaxValue;
Console.WriteLine(f); // 2.147484E+09, totally fine so far
var i = (int)f;
Console.WriteLine(i); // -2147483648, which is negative, no OverflowException

int.maxvalue to float将不是整数的确切表示,我也明白,将结果归还int32很可能很可能会由于如何在内存中表示浮点值,因此与我之前的情况不同。 这一切都很好。

但是我的天真期望是,像c#这样的思想直觉和美丽的语言实际上会导致system.OverFlowException第二次转换,这显然不是这样。

相比之下,编写以下内容确实已经给我们带来了编译时间错误,尽管基本上是这样做的(我知道,这是由编译器检查的,并且与RT行为并不相关):

int i = (int)(float)int.MaxValue;
// CS0221 Constant value '2.147484E+09' cannot be converted to a 'int' (use 'unchecked' syntax to override)

所以我的问题是:为什么.NET RT在这里不抛出例外?这种定义的行为是根据规格的吗?我找不到 ecma 334 解释了这一发现。 相反,请检查第11.3.2章显式数字转换”:

对于从浮点或double到积分类型的转换[...]源操作数朝零舍入到最近的积分值。如果这个 积分值在目标类型的范围内,那么此值是 转换。否则,将抛出系统。

我敢肯定,我不能成为第一个陷入这种行为的人,但是我在上面没有发现任何东西,所以我不认为这是一个RT错误,在.NET史上从未发现过。

I stumbled across quite an interesting behavior and want to ask, if somebody can explain me why the following is not throwing an OverflowException in .NET languages (checked with .NET 6):

var f = (float)int.MaxValue;
Console.WriteLine(f); // 2.147484E+09, totally fine so far
var i = (int)f;
Console.WriteLine(i); // -2147483648, which is negative, no OverflowException

So, I understand that casting int.MaxValue to float will not be an exact representation of an integer and I understand too, that casting the result back to Int32 will most likely be not the same as what I had before, due to how floating point values are represented in memory.
This is all fine.

But my naive expectation was, that a thought-through and beautiful language like C# would actually cause a System.OverflowException for the second conversion, which is apparently not the case.

In comparison, writing something like the following does already give us a compile time error, though basically doing the same (I know, I know, this is checked by the compiler and is not really related to the RT behavior):

int i = (int)(float)int.MaxValue;
// CS0221 Constant value '2.147484E+09' cannot be converted to a 'int' (use 'unchecked' syntax to override)

So my question is: Why is the .NET RT not throwing an exception here? Is this defined behavior according to the spec? I was not able to find anything in ECMA 334 which explains this discovery.
On the contrary, check chapter "11.3.2 Explicit numeric conversions":

For a conversion from float or double to an integral type [...] the source operand is rounded towards zero to the nearest integral value. If this
integral value is within the range of the destination type then this value is the result of the
conversion. Otherwise, a System.OverflowException is thrown.

I'm sure that I cannot be the first person stumbling across such behavior, but I did not find anything on SO explaining me that and I don't believe that this is a RT bug which was never discovered in the history of .NET.

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

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

发布评论

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

评论(1

冷︶言冷语的世界 2025-02-15 16:52:19

您需要手动从项目属性中手动启用“检查算术溢出” -GT;构建 - >先进的

You will need to manually enable 'Check for arithmetic overflow' from project properties -> build -> advanced

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