[英]Why casting big double value in sbyte returns 0 in C#?
我实际上在未经检查的上下文中测试了 C# 中的转换行为。 就像文档所说的那样,在未经检查的上下文中,演员表总是成功的。 但有时,在特定情况下,从一种特定类型到另一种类型的转换会产生意想不到的结果。
例如,我测试了三个“double to sbyte”类型转换:
var firstCast = (sbyte) -129.83297462979882752; // Result : 127.
var secondCast = (sbyte) -65324678217.74282742874973267; // Result : 0.
var thirdCast = (sbyte) -65324678216.74282742874973267; // Result : 0.
需要明确的是,第二个和第三个双secondDouble - firstDouble = 1
之间的差异仅为1
( secondDouble - firstDouble = 1
)。 在这种情况下,对于任何“大”双精度值,转换结果似乎总是0
。
我的问题是:为什么第二次和第三次转换结果为0
? 我在 C# 文档中搜索了答案,但没有找到。
我使用 .Net Framework 4.7.2 测试了上述内容。
根据C# 语言规范,
对于从 float 或 double 到整数类型的转换,处理取决于发生转换的溢出检查上下文:
不使用checked
或unchecked
操作符,默认溢出检查上下文是unchecked,所以我们看:
在未经检查的上下文中,转换总是成功,并按如下方式进行。
如果操作数的值为 NaN 或无穷大,则转换的结果是目标类型的未指定值。
否则,源操作数将向零舍入到最接近的整数值。 如果此整数值在目标类型的范围内,则此值是转换的结果。
否则,转换的结果是目标类型的未指定值。
这里的值既不是 NaN 也不是无穷大。 当向零舍入时,它们不在sbyte
的有效范围内,即 -128 到 127,因此最后一个要点适用,这意味着此类转换的结果未指定。
换句话说,此转换的结果取决于您使用的编译器。 不同的编译器可以做不同的事情,它们仍将被称为 C# 编译器。 很可能您使用的任何编译器都认为当要转换的值离下限/上限很远时,为转换返回 0 是一个更好的主意。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.