中间计算溢出错误。促进长期或直接加倍?

时间:2014-05-29 01:10:55

标签: c#

我使用了以下代码行:

points[x].TVAR = outerSum / (6 * n * n * outerΣMax);

outerSumTVARdouble,其余为int秒。我在括号中的代码计算为int和溢出。我应该将值提升为long还是double来克服此错误?它有所作为吗?

宣传到long

points[x].TVAR = outerSum / (6L * n * n * outerΣMax);

或宣传到double

points[x].TVAR = outerSum / (6.0 * n * n * outerΣMax);

修改

我在这里主要关心的不是精度损失,因为它最终会丢失,而是效率。从理论上推广intlong似乎比从intdouble推广更有效。 double操作还比long操作慢吗?也许我在思考/优化,但这正是我想要确定的。

3 个答案:

答案 0 :(得分:2)

由于outerSumdouble,您无论如何都会以double结束。这是因为Section 7.4.2的上下文中的重载决策规则,主要是Section 7.2.4。不久:

  

第7.4.2节的重载决策规则适用于候选运算符集,以便根据参数列表选择最佳运算符


  

给定适用的候选函数成员集,找到该集合中的最佳函数成员。

其中更好Section 7.4.2.3中定义,这意味着哪个重载是最佳

因此,首先转换为long毫无意义,对于阅读代码的人来说可能会感到困惑。因此,我认为推荐使用第二个版本。

答案 1 :(得分:0)

转换为double将是理想的,因为这最终是使用的类型。

从理论上讲,长期可以提供更高的准确度,但无论如何你都会很快失去它。

答案 2 :(得分:0)

每条评论因为只有内部计算溢出的n值很大,你可以使用checked语句有条件地进行转换(种类),如下所示。否则,由于outerSum是double类型,因此整个表达式outerSum / (6 * n * n * outerΣMax)将以double类型进行求值。

所以,只有当n溢出并引发异常时才会显示catch的大值,在 try { // The following line raises an exception because it is checked. points[x].TVAR = checked(outerSum / (6 * n * n * outerΣMax)); } catch (System.OverflowException e) { // The following line displays information about the error. points[x].TVAR = outerSum / (6.0 * n * n * outerΣMax); } 语句中,您要转换为double,这应该没问题。请参阅checked (C# Reference)

points[x].TVAR = (n >= 10000)? outerSum / (6.0 * n * n * outerΣMax) 
: outerSum / (6 * n * n * outerΣMax)

修改

另外,如果您可以找出n的特定大值(我的意思是起始值)溢出,那么只需使用if条件并相应地处理转换。

{{1}}