C# 计算过程中出现溢出错误。提升到长还是直到双?

C# 计算过程中出现溢出错误。提升到长还是直到双?,c#,C#,我使用了以下代码行: 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); 或升级到双倍: points[x].TVAR = outerSum / (6.0

我使用了以下代码行:

points[x].TVAR = outerSum / (6 * n * n * outerΣMax);
outerSum
TVAR
double
s,其余是
int
s。括号中的代码被计算为int并溢出。我应该将值提升为
long
还是
double
以克服此错误?这有区别吗

升级到
long

points[x].TVAR = outerSum / (6L * n * n * outerΣMax);
或升级到双倍

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


我在这里主要关心的不是精度的损失,因为它最终将丢失,而是效率。从理论上讲,从和
int
提升到
long
比从和
int
提升到
double
更有效。另外,
double
操作是否比
long
操作慢?也许我在考虑/优化,但这正是我试图确定的。

转换为双精度将是理想的,因为这是最终使用的类型


从理论上讲,long可以提供更高的准确性,但你很快就会失去它。

因为
outerSum
double
你最终会得到
double
。这是因为重载解析的规则,主要是在。很快:

第7.4.2节的重载解析规则适用于候选运算符集,以选择与参数列表相关的最佳运算符


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

在中定义了better,这意味着哪个重载是最好的


因此,一开始转换为
long
是毫无意义的,可能会让阅读您代码的人感到困惑。因此,我认为建议使用第二个版本。

每个注释,因为只有对于较大的n值,内部计算溢出,您可以使用下面的
checked
语句有条件地(某种程度上)进行转换。否则,由于
outerSum
是双类型,整个表达式
outerSum/(6*n*n*outer∑Max)
将以双类型计算

因此,只有当
n
的大值溢出并引发异常时,在
catch
语句中,您将转换为double,应该可以。了解

编辑:

另外,如果您能找到哪个特定的大值n(我是指起始值)溢出发生,那么只需使用if条件并相应地处理您的转换

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

只是为了溢出的目的,它是好的;否则,因为outerSum是双精度类型,所以整个表达式将导致double。@Rahul:如果您很快要使用double,我觉得使用long似乎有些迂回。对于
n
的所有值,内部计算是否溢出?或仅适用于较大的n@Rahul仅适用于较大的n值。如果您关心哪个更快,请询问您的计算机,而不是我们。乘法可能比双精度乘法慢,但除法可能更快。你可以比我们更好地回答这个问题。@Fr33dan你肯定是在思考/优化。首先,你是基于一种盲目的猜测,即“对你来说似乎更快”(不确定“理论上”部分在那里做什么,如果是“对你”:p)——这没有意义。其次,这些行动之间的差异几乎总是可以忽略不计的。你在浪费时间考虑这个。只要测量两个版本的执行时间,就会发现对这一点的疑惑是毫无意义的:)@BartoszKP“在理论上对我来说”意味着“根据我对理论的理解”。请不要取笑我说话的方式,如果不清楚,请要求澄清。需要移动/设置更少的位以提升为
,并且无需检查有效位的大小,这似乎更快。至于测量它,这只会告诉我它是如何在我的CPU架构上运行的。它在x86和x64上的行为可能不同。但是,我确实认为我读了别人的评论后工作过度,可能只会使用
double
,不再考虑它。此操作是在O(N²)(而不是
N
)操作中运行的。可能捕获到一个异常,该异常在很多情况下似乎效率很低。当我说“更大的价值”时,它可能是它们的一半
n
不会线性增加。@Fr33dan,请更正它,但这也避免了使其完全双重类型。根据您的要求,这只是一个可能/可能不适合的替代方案。在这种情况下,您最好使用
6.0*n*n*outer∑Max
这是一个有趣的想法,但我不确定它是否更有效,因为您正在添加一个操作。@Fr33dan,额外的操作是条件检查,它不会占用太多时间。使用秒表
类,检查有/没有额外条件检查需要多长时间。我相信你们不会看到太大的区别。你们说“使用下面的检查语句”,然后展示一些没有任何“检查”语句的示例代码,这很令人困惑——至少我看不到。你们的答案充满了好的信息,但不是我想要的。请参阅对我的问题的编辑。
points[x].TVAR = (n >= 10000)? outerSum / (6.0 * n * n * outerΣMax) 
: outerSum / (6 * n * n * outerΣMax)