Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何防止sqrt中的溢出?_C++_Math_Sqrt - Fatal编程技术网

C++ 如何防止sqrt中的溢出?

C++ 如何防止sqrt中的溢出?,c++,math,sqrt,C++,Math,Sqrt,我有密码 unsigned long long f(unsigned long long x, unsigned long long y){ return sqrt( ( (5*x*x + 1) * (5*y*y +1) - 1 ) / 4 ); } 但是如果x或y太大,即使输出应该很小,也会溢出。有办法解决这个问题吗 也许可以用代数方法将平方根的参数拆分为: return sqrt((3*x*x+1)/2) * sqrt((6*y*y-5)/2); 或者根据您的需要

我有密码

unsigned long long f(unsigned long long x, unsigned long long y){
   return sqrt( ( (5*x*x + 1) * (5*y*y +1) - 1 ) / 4 );         
}

但是如果x或y太大,即使输出应该很小,也会溢出。有办法解决这个问题吗

也许可以用代数方法将平方根的参数拆分为:

return sqrt((3*x*x+1)/2) * sqrt((6*y*y-5)/2);
或者根据您的需要将其进一步拆分

如果
x
足够大,您可以忽略
+1
并生成第一个术语:

sqrt((3*x*x)/2) = fabs(x) * sqrt(3.0/2.0)
同样地,对于第二个术语,使用
y
,使其

sqrt((6*y*y)/2) = fabs(y) * sqrt(3.0);
编辑:OP将其问题编辑为:

return sqrt(((3*x*x+1)*(6*y*y-5)-1)/4);  
事实上,你可以把事情分开。你只要再小心一点就行了。底线是,如果
x
非常大,那么
+1
可以忽略。如果
y
非常大,则可以忽略
-5
。如果
(3*x*x+1)
(6*y*y-5)
都是正数,并且两者都很大,那么
-1
可以忽略。您可以使用这些技巧和一些附加的外围逻辑来进一步分解这一点。像这样:

 if(fabs(x) > BIGNUMBER && fabs(y) > BIGNUMBER)
 {
     return fabs(x) * fabs(y) * sqrt(18.0/4.0);
 }
 if(fabs(x) > BIGNUMBER && fabs(y) > 1.0)  // x big and y term positive
 {
     return fabs(x) * sqrt(6*y*y-5) * sqrt(3.0/2.0);
 }
 if(fabs(y) > BIGNUMBER)  // x term positive and y big
 {
     return sqrt(3*x*x+1) * fabs(y) * sqrt(6.0/2.0);
 }
 return sqrt(((3*x*x+1)*(6*y*y-5)-1)/4); 

你可以对此进行优化,但这只是为了说明这一点。

我相信在大x或y下,-1可以忽略w.r.t(x*x)*(y*y)。。。由于函数返回long-long,因此浮点精度无关紧要


你可以检查x或y是否大,因此,你可以选择忽略-1,按照Chris或Rob说的去做。

你需要一个多精确的答案?重命名你的函数…这是非常不明显的它应该做什么。还有templatetypedef说了些什么。@Brendan:你有没有想过这可能是某些礼仪规范的一部分,而且对
f
使用实名可能会违反OP的保密协议?例如,
f
可以。@Brendan:…或者它只是作为一个示例,在本例中,函数名完全不相关?
sqrt
不会溢出。当然你一定是指计算结果。注意:由于整数除法,
sqrt(3/2)
=
sqrt(1)
=
1
@Robᵩ 说得好,我换了一种更具符号性的符号,但我会纠正这个C/C++的错误。@Againsticilian同样的概念也适用。我不能将它分为两个产品,因为我有一个-1,很幸运,我已经尝试了Wolfram。如果我能做到的话,我就不会把问题贴出来了!:)