为什么在sbyte中强制转换大的double值在C#中返回0? [英] Why casting big double value in sbyte returns 0 in C#?

查看:76
本文介绍了为什么在sbyte中强制转换大的double值在C#中返回0?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我实际上在未经检查的上下文中测试了C#中的转换行为。就像文档中所说的那样,在未经检查的上下文中,强制转换总是成功的。但是有时,在特定情况下,从一种特定类型到另一种类型的转换会产生意外的结果。

I actually test the casting behavior in C# in unchecked context. Like the documentation said, in unchecked context, the cast always succeed. But sometimes, in particular cases, the cast from one specific type to another type give unexpected result.

例如,我测试了三个 double to sbyte转换:

For example, i tested three "double to sbyte" casts :

var firstCast = (sbyte) -129.83297462979882752;          // Result : 127.
var secondCast = (sbyte) -65324678217.74282742874973267; // Result : 0.
var thirdCast = (sbyte) -65324678216.74282742874973267;  // Result : 0.

请注意,第二个和第三个double之间的差是只需 1 secondDouble-firstDouble = 1 )。
在这种情况下,对于任何大双精度值,强制转换的结果似乎总是 0

Just to be clear, the difference between the second and the third double is just 1 (secondDouble - firstDouble = 1). In this case, results of casting seem to always be 0 for any "big" double value.

我的问题是:为什么第二和第三次强制转换导致 0
我在C#文档中搜索了答案,但没有找到任何答案。

My question is : why the second and the third casts result in 0 ? I searched for an answer in the C# documentation, but i did not find any.

我使用.Net Framework 4.7.2测试了上述内容。

I tested the above with the .Net Framework 4.7.2.

推荐答案

根据 C#语言规范


从float或double到整型,处理取决于发生转换的溢出检查上下文:

For a conversion from float or double to an integral type, the processing depends on the overflow checking context in which the conversion takes place:

不使用 checked unchecked 运算符,默认情况下,未选中溢出检查上下文,因此我们来看:

Without using the checked or unchecked operators, by default the overflow checking context is unchecked, so we look at:

在未经检查的上下文中,转换始终会成功,并按如下方式进行。

In an unchecked context, the conversion always succeeds, and proceeds as follows.


  • 如果操作数是NaN或无穷大,转换结果是th的未指定值

  • If the value of the operand is NaN or infinite, the result of the conversion is an unspecified value of the destination type.

否则,源操作数将朝四舍五入到最接近的整数值。如果此整数值在目标类型的范围内,则此值是转换的结果。

Otherwise, 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, the result of the conversion is an unspecified value of the destination type.

此处,这些值是NaN或无限。当四舍五入为零时,它们不在有效的 sbyte 范围内,即-128到127,因此最后一个要点适用,这意味着这样的结果

Here, the values are neither NaN nor infinite. When rounded towards zero, they are not in the valid range of sbyte, which is -128 to 127, therefore the last bullet point applies, which means that the result of such a cast is unspecified.

换句话说,该强制转换的结果取决于您使用的编译器。不同的编译器可以做不同的事情,它们仍将被称为C#编译器。

In other words, the result of this cast depends on which compiler you are using. Different compilers could do different things, and they will still be called C# compilers. It is likely that whatever compiler that you are using just thought it'd be a better idea to return 0 for the conversion when the value to convert is very far away the lower/upper bound.

这篇关于为什么在sbyte中强制转换大的double值在C#中返回0?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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