Double.MaxValue 到整数是负数? [英] Double.MaxValue to integer is negative?

查看:30
本文介绍了Double.MaxValue 到整数是负数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么 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.

对于从 doubledecimal 的转换:如果源值为 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 到整数是负数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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