Simple double-precision add problem
by Valador, Inc. · in Torque Game Engine Advanced · 01/20/2009 (10:31 am) · 5 replies
Hi there.
I've been trying to change my copy of the engine to support double-precision floating-point values in script. So far,so good. Then this issue came up.
Please note the below code:
const char *CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNamespace, U32 argc, const char **argv, bool noCalls, StringTableEntry packageName, S32 setFrame)
{
...
case OP_ADD:
floatStack[FLT-1] = floatStack[FLT] + floatStack[FLT-1];
FLT--;
break;
...
}
The simple add above is somehow not being processed properly.
If
floatStack[FLT] 32343.235253242525 double
floatStack[FLT-1] 4.5300000000000002 double
then
floatStack[FLT-1], after the add operation above, should be equal to 32347.765253242525. But instead, it's equal to 32347.765625.
Somehow, a significant loss of precision/error has occurred here. And I'm not sure why. After all, if I create a new executable, with just this code:
int main()
{
double rhs=32343.235253242525;
double lhs=4.53;
double result=lhs+rhs;
return 0;
}
lhs 4.5300000000000002 double
rhs 32343.235253242525 double
result 32347.765253242524 double
The above result is exactly what I'd normally expect.
I do know that floatStack[FLT] and floatStack[FLT-1], by default, contain single-precision values cast to double-precision. But nevertheless, this is a simple double-precision add. And I'm only having this strange double-precision add behavior in TGEA 1.8 code, and nowhere else.
I was thinking this had something to do with intrinsic functions begin enabled. On/off, (/iO), makes no difference. /fp:strict, or /fp:precise, makes no difference. I'm still thinking there's a simple answer to this problem that I'm overlooking. I just don't know what it is.
Please help :(
Thanks
Franklin
I've been trying to change my copy of the engine to support double-precision floating-point values in script. So far,so good. Then this issue came up.
Please note the below code:
const char *CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNamespace, U32 argc, const char **argv, bool noCalls, StringTableEntry packageName, S32 setFrame)
{
...
case OP_ADD:
floatStack[FLT-1] = floatStack[FLT] + floatStack[FLT-1];
FLT--;
break;
...
}
The simple add above is somehow not being processed properly.
If
floatStack[FLT] 32343.235253242525 double
floatStack[FLT-1] 4.5300000000000002 double
then
floatStack[FLT-1], after the add operation above, should be equal to 32347.765253242525. But instead, it's equal to 32347.765625.
Somehow, a significant loss of precision/error has occurred here. And I'm not sure why. After all, if I create a new executable, with just this code:
int main()
{
double rhs=32343.235253242525;
double lhs=4.53;
double result=lhs+rhs;
return 0;
}
lhs 4.5300000000000002 double
rhs 32343.235253242525 double
result 32347.765253242524 double
The above result is exactly what I'd normally expect.
I do know that floatStack[FLT] and floatStack[FLT-1], by default, contain single-precision values cast to double-precision. But nevertheless, this is a simple double-precision add. And I'm only having this strange double-precision add behavior in TGEA 1.8 code, and nowhere else.
I was thinking this had something to do with intrinsic functions begin enabled. On/off, (/iO), makes no difference. /fp:strict, or /fp:precise, makes no difference. I'm still thinking there's a simple answer to this problem that I'm overlooking. I just don't know what it is.
Please help :(
Thanks
Franklin
#2
I know this was mentioned on the forums before so if you feel fancy, go try and find it. It was definatly before 2007, and in the TGE forums. It might or might not be related to your issue, but if you haven't yet changed this spot, then it absolutely will limit any 64-bitness in script that you try to implement.
01/20/2009 (12:30 pm)
If this is entirely script-related, then I'll bet my right foot it's an issue we saw a few years ago. Somewhere in the script engine, there are a few spots with sprintf () calls, and they are limiting precision to a certain amount of bytes length (Ie, when the conversion from string to F32/F64 happens - think %.6f) but it's so long ago I'm not sure where it is in the source, if it's still there at all.I know this was mentioned on the forums before so if you feel fancy, go try and find it. It was definatly before 2007, and in the TGE forums. It might or might not be related to your issue, but if you haven't yet changed this spot, then it absolutely will limit any 64-bitness in script that you try to implement.
#3
Ended up being a issue with a string being converted to F32/F64 or similar to that.
Might be the same issue you where talking about Stefan from long ago.
01/20/2009 (2:22 pm)
I think this was also the cause of the flaky camera at extreme distances in a mission. Example when you take a car or spaceship and fly it for an extensive distance in one direction and the location values start to become very large. It results in the camera starting to shack all flaky like.Ended up being a issue with a string being converted to F32/F64 or similar to that.
Might be the same issue you where talking about Stefan from long ago.
#4
01/20/2009 (3:51 pm)
Most likely. I just wish I remember more than I do. :/
#5
I will keep a eye out for it though.
01/20/2009 (4:13 pm)
I tried to find the post / blog / where ever I seen it at. But I just couldn't find it. I thought it was a post by Bill since he hsa been working on a large scale space game. But I just couldn't find it through the search system.I will keep a eye out for it though.
Torque 3D Owner Chris