Gamestudio Links
Zorro Links
Newest Posts
Data from CSV not parsed correctly
by dr_panther. 05/06/24 18:50
Help with plotting multiple ZigZag
by degenerate_762. 04/30/24 23:23
M1 Oversampling
by 11honza11. 04/30/24 08:16
AUM Magazine
Latest Screens
The Bible Game
A psychological thriller game
SHADOW (2014)
DEAD TASTE
Who's Online Now
1 registered members (AndrewAMD), 831 guests, and 5 spiders.
Key: Admin, Global Mod, Mod
Newest Members
firatv, wandaluciaia, Mega_Rod, EternallyCurious, howardR
19050 Registered Users
Previous Thread
Next Thread
Print Thread
Rate Thread
Math issue in c-script #215359
07/10/08 18:13
07/10/08 18:13
Joined: Feb 2006
Posts: 2,185
mpdeveloper_B Offline OP
Expert
mpdeveloper_B  Offline 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
F
Fenriswolf Offline
Member
Fenriswolf  Offline
Member
F

Joined: Jan 2007
Posts: 221
Hello,

have a look at the manual page about Variables:
Quote:
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 Offline
Newbie
pfeldman  Offline
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 Offline

Moderator
Tobias  Offline

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 Offline

Chief Engineer
jcl  Offline

Chief Engineer

Joined: Jul 2000
Posts: 27,986
Frankfurt
For anyone interested, you multiply and divide fixed point numbers with this code:
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
	}
}


Re: Math issue in c-script [Re: jcl] #224028
08/28/08 02:45
08/28/08 02:45
Joined: Jun 2008
Posts: 40
pfeldman Offline
Newbie
pfeldman  Offline
Newbie

Joined: Jun 2008
Posts: 40
Firstly, I'd like to thank Tobias and jcl for taking the time to respond.

I had taken the statement about the precision equalling 0.001 literally, and made the false assumption that a var represents a number using a "pseudo-decimal point", i.e., that a number z is represented internally via the binary form of the integer 1000*z. In such a system, 0.5 would be stored as (111110100)binary= (500)decimal. The pseudo-decimal point approach is perfectly reasonable, and is often used for calculations involving money, for obvious reasons.

Back to Lite-C: With 10 bits to the right of the binary point, the closest representation of 1.05 is round(1.05 * 1024) / 1024= round(1075.2) / 1024 = 1075/1024= 1.0498. 60 * 1.0498= 62.988, so everything checks.

I'm still unclear about the following: Consider the expression 60.0 * str_to_num(str). It looks as though Lite-C automatically treats the 60.0 and the result of the str_to_num() function as vars rather than floats. I can't find anything in the manual that says that var is the default type. It would be good if this can be clarified.

Re: Math issue in c-script [Re: pfeldman] #224033
08/28/08 04:35
08/28/08 04:35
Joined: Jul 2008
Posts: 553
Singapore
delinkx Offline
User
delinkx  Offline
User

Joined: Jul 2008
Posts: 553
Singapore
i tried this on my engine. i alwys get a proper 1.000

var tmpnum;

function compute()
{
tmpnum = 100 * 0.01;
}

I have the A7.10 engine.


A7 commercial Team / VC++ 2008 Pro
homepage | twitter | facebook
Re: Math issue in c-script [Re: delinkx] #224046
08/28/08 08:29
08/28/08 08:29
Joined: Jul 2000
Posts: 27,986
Frankfurt
jcl Offline

Chief Engineer
jcl  Offline

Chief Engineer

Joined: Jul 2000
Posts: 27,986
Frankfurt
The default type in all C languages is double for constants with a decimal point, and int for constants without decimal point. It's the same in lite-C.

"60.0" is a float. "100 * 0.01" is the same as the double 1.00. However when you multiply two vars that contain 100 and 0.01, you'll get a result different from 1.00 due to the 1/1024 precision.


Moderated by  old_bill, Tobias 

Gamestudio download | chip programmers | Zorro platform | shop | Data Protection Policy

oP group Germany GmbH | Birkenstr. 25-27 | 63549 Ronneburg / Germany | info (at) opgroup.de

Powered by UBB.threads™ PHP Forum Software 7.7.1