1 registered members (AndrewAMD),
831
guests, and 5
spiders. |
Key:
Admin,
Global Mod,
Mod
|
|
|
Math issue in c-script
#215359
07/10/08 18:13
07/10/08 18:13
|
Joined: Feb 2006
Posts: 2,185
mpdeveloper_B
OP
Expert
|
OP
Expert
Joined: Feb 2006
Posts: 2,185
|
I have an odd one here, first of all I noticed that my script was behaving oddly when I tried to use exact values (in this instance between 0 and 1) when I noticed that it was outputting the wrong number in a variable. The equation is this:
tmpnum = 100 * 0.01;
according to proper calculations tmpnum would equal 1, but according to the engine it equals something around 0.97656 .
Umm...why is this? This could cause serious errors in bigger equations...
edit: thought I'd mention:
Engine Version: A6.6 no time variable used, just exact values.
edit2: I noticed that if I used:
tmpnum = 100 / 100;
it gives me the proper number, but why is it that the decimal points have an issue?
- aka Manslayer101
|
|
|
Re: Math issue in c-script
[Re: mpdeveloper_B]
#215362
07/10/08 18:24
07/10/08 18:24
|
Joined: Jan 2007
Posts: 221
Fenriswolf
Member
|
Member
Joined: Jan 2007
Posts: 221
|
Hello, have a look at the manual page about Variables: Computers always perform their calculations with finite accuracy. The "general purpose" var variables can store numbers, pointers, or handles. Numbers are stored in fixed point format in the range of -999999.999..+999999.999 with a precision of 0.001. This is sufficient in all normal cases for calculating coordinates, angles or anything you need in a virtual world. However, care must be taken when calculating with extremely large or extremely small values. For instance, a multiplication by 100 has an inaccuracy of 0.001/100 = 0.001%, while the result of a division by 0.01 - mathematically the same - is inaccurate by 0.001/0.01 = 10%!
|
|
|
Re: Math issue in c-script
[Re: Fenriswolf]
#223423
08/24/08 06:19
08/24/08 06:19
|
Joined: Jun 2008
Posts: 40
pfeldman
Newbie
|
Newbie
Joined: Jun 2008
Posts: 40
|
The manual does not specify how operations such as multiplication are being done. As a former lecturer in computer science, I would expect the engine to use a higher-precision representation while doing a multiplication or division, and then convert the final result back into the var format, but it seems as though this isn't happening. If one runs the following program, which multiplies numbers by 60, and enters 1.05, one finds that 60*1.05= 62.988. The Lite-C engine should be able to do multiplications with a relative error of plus or minor 1e-6. With a relative error of -1e-6, 60*1.05 would come out as 62.999937, which would then round to 63.000 when converted back into the var format. So, it seems as though the Lite-C designers have done something wrong here.
#include <acknex.h> #include <default.c>
TEXT* prompt= { pos_x = 100; pos_y = 60; font = "Arial#24bi"; flags= VISIBLE; strings= 1; }
STRING* user_input_str= " "; // initialized to 12 blanks
TEXT* user_input_txt= { pos_x = 200; pos_y = 100; font = "Arial#24bi"; string(user_input_str); flags= VISIBLE; }
TEXT* result_txt= { pos_x = 200; pos_y = 300; font = "Arial#60b"; flags= VISIBLE; strings= 1; }
function main() {
video_mode = 7; // create a program window of 800x600 pixels screen_color.blue = 50; // and make its background dark blue
// Display prompt: str_cpy( (prompt.pstring)[0], "Enter a number x: ");
// Wait for user to type something (or nothing) followed by Enter: inkey(user_input_str);
// Display result: str_cpy( (result_txt.pstring)[0], "60 x= "); str_cat_num( (result_txt.pstring)[0], "%0.3f", 60.0 * str_to_num(user_input_str));
}
|
|
|
Re: Math issue in c-script
[Re: pfeldman]
#223437
08/24/08 08:44
08/24/08 08:44
|
Joined: Aug 2000
Posts: 1,140 Baunatal, Germany
Tobias
Moderator
|
Moderator
Joined: Aug 2000
Posts: 1,140
Baunatal, Germany
|
The problem is that computers calculate binary, not decimal as you seem to assume in your example. A var is 32 bits and has 10 bits fixed point, hence the precision, 10 bits = 1024 and 1/1024 = 0.001. Now you notice the 1024, not 1000? Thats because of the binary calculation, and thats why rounding does not end up with your 63.000, you normally get some odd number instead. Multiplication of 32 bit vars on a PC results in 64 bit, and as the vars have a precision of 0.001 the interim result can only have a precision of 0.0005 and not "1e-6". Then the result is shifted back to 32 bit, ending up with 10 bits fixed point and 0.001 precision again. If I remember right Conitec has posted here some time ago the assembler functions they use for multiplying and dividing vars, but I cant find them anymore.
For higher precision than 0.001, in any computer language you have to use float or double.
Ok this was a little technical but anyway I hope this helps to understand variables?
|
|
|
Re: Math issue in c-script
[Re: Tobias]
#223577
08/25/08 09:06
08/25/08 09:06
|
Joined: Jul 2000
Posts: 27,986 Frankfurt
jcl
Chief Engineer
|
Chief Engineer
Joined: Jul 2000
Posts: 27,986
Frankfurt
|
For anyone interested, you multiply and divide fixed point numbers with this code: inline var fixmul(var r1,var r2)
{
__asm {
mov eax,r1
mov edx,r2
imul edx
shrd eax,edx,10
adc eax,0
}
}
inline var fixdiv(var dividend, var divisor)
{
__asm {
mov eax,dividend
mov ecx,divisor
mov edx,eax
sar edx,22
shl eax,10
idiv ecx
}
}
|
|
|
|