我使用了以下代码:
points[x].TVAR = outerSum / (6 * n * n * outerΣMax);outerSum和TVAR是doubles,其余是ints。括号中的代码被计算为int和溢出。是否应该将值提升到long或double以克服此错误?有什么不同吗?
推广到long
points[x].TVAR = outerSum / (6L * n * n * outerΣMax);或晋升到double
points[x].TVAR = outerSum / (6.0 * n * n * outerΣMax);编辑:
我在这里主要关心的不是失去精确性,因为它最终将失去,而是效率。从理论上讲,将from和int提升到long似乎比将from和int提升到double更有效。另外,double操作比long操作慢吗?也许我已经过度思考/优化了,但这正是我想要确定的。
发布于 2014-05-29 01:17:50
由于outerSum是double,所以您最终还是会使用double。这是因为重载解析规则,主要是第7.4.2节,在第7.2.4节上下文中。短期内:
第7.4.2节的过载解析规则应用于候选操作符集,以便根据参数列表选择最佳运算符
给定适用的候选函数成员集,该集合中的最佳功能成员被定位。
在第7.4.2.3节中定义了更好的地方,这意味着哪种重载是最好的。
因此,一开始转换为long是没有意义的,而且可能会让阅读您的代码的人感到困惑。因此,我认为第二个版本是推荐的。
发布于 2014-05-29 01:16:57
转换为double将是理想的,因为这是最终使用的类型。
理论上,long可以提供更多的准确性,但无论如何,你很快就会失去它。
发布于 2014-05-29 01:24:01
根据注释,因为仅对于n个大值的内部计算溢出,您可以使用checked语句进行有条件(某种程度)的转换,如下所示。否则,由于outerSum是双类型的,所以整个表达式outerSum / (6 * n * n * outerΣMax)将计算为double类型。
因此,只有当n的值溢出并引发异常时,您才会在catch语句中将其转换为double,这应该会很好。见检查(C#参考)
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);
}编辑:
此外,如果您能够发现特定的大值n(我指的是起始值)溢出,那么只需使用一个if条件,并相应地处理您的转换。
points[x].TVAR = (n >= 10000)? outerSum / (6.0 * n * n * outerΣMax)
: outerSum / (6 * n * n * outerΣMax)https://stackoverflow.com/questions/23924263
复制相似问题