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)