问题描述
为什么 Double.MaxValue
转换为整数类型会导致负值,该类型的最小值?
Why does Double.MaxValue
casted to an integral type results in a negative value, the smallest value of that type?
double maxDouble = double.MaxValue; // 1.7976931348623157E+308
long maxDoubleLong = (long) maxDouble; // -9223372036854775808
如果编译器错误太大或在运行时出现 OverflowException
或者如果我使用 unchecked
转换可能不会引发异常,我会理解编译器错误,但是结果变得不确定和不正确(负).
I'd understand a compiler error if it's too large or an OverflowException
at runtime or if i'd use unchecked
that the conversion might not throw an exception, but the result becomes undefined and incorrect(negative).
同样奇怪的是该值是 long.最小值
:
Also strange is that the value is long.MinValue
:
bool sameAsLongMin = maxDoubleLong == long.MinValue; // true
顺便说一句,如果我将其转换为 int
,也会发生同样的情况:
By the way, the same happens if i cast it to int
:
int maxDoubleInt = (int)maxDouble; // -2147483648
bool sameAsIntMin = maxDoubleInt == int.MinValue; // true
如果它尝试将其转换为 decimal
我会在运行时得到一个 OverflowException
If it try to cast it to decimal
i get an OverflowException
at runtime
decimal maxDoubleDec = (decimal)maxDouble; // nope
更新:似乎 Michael 和 Barre 的回答一针见血,如果我明确使用 checked
我会得到一个 OverflowException
:
Update: it seems that Michael's and Barre's answers hit the nail on the head, if i use checked
explicitly i get an OverflowException
:
checked
{
double maxDouble = double.MaxValue; // 1.7976931348623157E+308
long maxDoubleLong = (long) maxDouble; // nope
}
推荐答案
C# 语言规范(5.0 版)在 6.2.1显式数字转换"(添加了重点)中说明了以下内容:
The C# Language Specification (Version 5.0) says the following in 6.2.1 "Explicit numeric conversions" (emphasis added):
对于从 float 或 double 到整数类型的转换,处理取决于溢出检查上下文(第 7.6.12 节),其中转换发生:
For a conversion from float or double to an integral type, the processing depends on the overflow checking context (§7.6.12) in which the conversion takes place:
在检查的上下文中,转换过程如下:
In a checked context, the conversion proceeds as follows:
- 如果操作数的值为 NaN 或无穷大,则抛出 System.OverflowException.
- 否则,源操作数会向零舍入到最接近的整数值.如果这个整数值在目标类型,那么这个值就是转换的结果.
- 否则,将引发 System.OverflowException.
在未经检查的上下文中,转换始终成功,并按如下方式进行.
In an unchecked context, the conversion always succeeds, and proceeds as follows.
- 如果操作数的值为 NaN 或无穷大,则转换的结果是目标类型的未指定值.
- 否则,源操作数会向零舍入到最接近的整数值.如果这个整数值在目标类型,那么这个值就是转换的结果.
- 否则,转换的结果是目标类型的未指定值.
在 7.6.12 中检查和未检查的操作符"
And in 7.6.12 "The checked and unchecked operators"
对于非常量表达式(在运行时)未包含在任何已检查或未检查的运算符中或语句,默认溢出检查上下文未选中除非外部因素(例如编译器切换和执行环境配置)要求检查评估.
For non-constant expressions (expressions that are evaluated at run-time) that are not enclosed by any checked or unchecked operators or statements, the default overflow checking context is unchecked unless external factors (such as compiler switches and execution environment configuration) call for checked evaluation.
对于从 double
到 decimal
的转换:如果源值为 NaN、无穷大或太大而无法表示为小数,则抛出 System.OverflowException".checked
vs unchecked
不起作用(那些只处理积分运算).
For conversions from double
to decimal
: "If the source value is NaN, infinity, or too large to represent as a decimal, a System.OverflowException is thrown". checked
vs unchecked
doesn't come into play (those deal with integral operations only).
这篇关于Double.MaxValue 到整数是负数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!