Split the argument of the square root up algebraically, maybe?:
return sqrt((3*x*x+1)/2) * sqrt((6*y*y-5)/2);
Or split it up further based on your needs.
If x
is big enough you can ignore the +1
and make the first term:
sqrt((3*x*x)/2) = fabs(x) * sqrt(3.0/2.0)
and similarly with y
for the second term, making it
sqrt((6*y*y)/2) = fabs(y) * sqrt(3.0);
EDIT: After OP edited his question to be:
return sqrt(((3*x*x+1)*(6*y*y-5)-1)/4);
You can in fact split things up. You just have to be a little bit more careful. Bottom line is that if x
is really big, then the +1
can be ignored. If y
is really big then the -5
can be ignored. If both (3*x*x+1)
and (6*y*y-5)
are positive and either is really big, then the -1
can be ignored. You can use these tips and some additional surrounding logic to break this down a bit further. Like this:
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);
You can optimize this, but this is just meant to show the point.
f
might violate the OP's NDA? For example purposes,f
is fine. – Mercaptopurinesqrt
won't overflow. Surely you must mean the computations leading up to it. – Tundrax
andy
? Or is it possible that one is very large and the other very small (in absolute value)? – Mckinneyy/2
out of the square root. Mathematically,sqrt(e*y*y) == abs(y)*sqrt(e)
, sosqrt(((5*x*x+1)*(5*y*y+1)-1)/4)
becomesfabs(y)*0.5*sqrt((5*x*x+1)*(5 + 1/(y*y)) - 1/(y*y))
. For most uses that's precise enough and avoids overflow. If that's not precise enough, you'll probably need a different datatype anyway. – Mckinneydouble
s. Cast todouble
for the division then,1/((double)y*y)
. – Mckinneydouble
can store integers< 2^53
, roughly10^15
exactly. But if you want to know whether the expression under the square root is a perfect square, i.e. the square root is an integer, you have to be aware of floating point errors. The computed result may be an integer even though the exact result isn't, and if intermediate results are too large to be represented exactly, it might turn out the other way. What exactly are you trying to do? There may be better methods. – Mckinney