#153666 - TheMagnitude - Thu Apr 03, 2008 5:34 pm
Ive read the wikipedia entry for fixed point numbers but I still don't understand how I would implement and use them in programming :(
#153672 - sniper - Thu Apr 03, 2008 7:45 pm
Fixed Point is simply multiply the values and calculate with the bigger values to get a fraction part of the resulting values.
means:
X/Y --> (X*100)/Y .. the result is 100 times bigger but has a fraction part.
X = 1, Y = 10
1/10 = 0 (Integer)
(1*100)/10 = 10 (means 10/100 = 0.1 )
For example if you want calculate:
X = X + 0.1, 1000 times.
with floating point you can do it like this:
Code: |
int i;
double x = 0.0;
for( i=0; i<1000; i++ )
{
x = x + 0.1;
}
printf("x must be 100: %f", x); |
with integer you cannot calulate this because 0.1 is 0.
without floating point types you can multiply the value x and the adder by 100. Then you have to devide the result by 100 to get the real value.
Code: |
int i;
int x = 0;
for( i=0; i<1000; i++ )
{
x = x + (1*100)/10; // 1*100/10 = 0.1*100
}
printf("x must be 100: %d", x/100); |
And get the same result (100).
For speedups (no multiplications/division) usually u use shift operators:
Code: |
int i;
int x = 0;
for( i=0; i<1000; i++ )
{
x = x + (1<<12)/10; // 1*4096/10 = 0.1*4096
}
printf("x must be 100: %d", x>>12); |
But you see the result is 99 instead of 100, so it is not that accurate as double but acceptable.
I hope it is understandable and helpful for you ;)
#153675 - elhobbs - Thu Apr 03, 2008 8:48 pm
you can use the macros provided with libnds. look in arm9\math.h and arm9\videogl.h use the f32 datatype. use normal +/- for addition and subtraction and the functions divf32 and mulf32 for division and multiplication respectively. There are even macro to convert from integer or float to f32 - inttof32 and floattof32.
good luck
#153676 - Dwedit - Thu Apr 03, 2008 8:51 pm
Which compilers DON'T automatically convert multiplication by powers of 2 to shifts?
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."
#153677 - sniper - Thu Apr 03, 2008 9:05 pm
Some in case muls/divs has the same speed as shifts but then its not required ;P
C is only an example. If you code it in asm you have to take care about it of cause.
#153700 - DensitY - Fri Apr 04, 2008 2:05 am
Fixed point Math is a way todo floating point using integers
basically entire idea is to shift whole numbers up into the higher bit ranges of an integer and using the lower bits as a the fractional range
for example lets take a 16bit integer, and convert it to a 8.8 format
say converting a standard integer to fixed point integer
Fp value = whole Number << 8;
here we're shifting the whole number up 8 bits into the 16 bit integer, modifying the lower 8 bits your actually modifing the fractional of the whole number.
to convert a floating point number its rather simple in this case
fp value = floatpoint number * (1<<8)
its the same conditions in terms of changing it back. but in general you avoid floats on the DS if possible along with dividing.
ok now there is some rules to remember with fixed point, and thats basically what happens to a number if you multiply it by a fixed point value (and same if you multiply by fixed point) and also what do you need todo to add.
Multiply rules
1.Multiplying a Fixed point value by a standard integer results in a fixed point value. ie
fixed value = Fixed value * standard int value
2. multiplying 2 fixed point values together actually increases fractional side of the fixed point value by 2. For example
8.16 = 8.8 * 8.8
so todo this correctly you have todo this to chip off the extra 8 bits of fraction data we don't need.
8.8 = (8.8 * 8.8) >> 8
the same rules apply for division as well.
Adding Rules.
- Adding Fixed by a standard integer number will result in you just increasing the value by a faction instead of the intended whole number
ie
incorrect fixed result = fixed number + whole number
so to ensure you increase it by the correct hole number range you have todo
fixed result = fixed number + (whole number << 8)
SOO... how is this useful?
well libnds has a fixed point SIN and COS map (which you have to correct by 4 bits but you'll work that out), this means that we can move things around ie
fstepx = COS[ANGLE & 0x1FF] >> 4;
fstepy = SIN[ANGLE & 0x1FF] >> 4;
then do
Player x += fstepx;
player y += fstepy;
todo "floating point" fractional movement without using floating point variables which are emulated and slow on the DS hardware.
you can also do a string of abusive tricks, ie a simple optimization back in the old PC days when division was painfully slow was todo something like
result = something * 0.5
instead of
result = something / 2
on the DS you could do something like this in fixed point to simulate a divide by 2
result = (something * 128 ) >> 8
the 128 is actually 0.5 if 8.8 fixed point the result of 0.5 * (1<<8).
um, hopefully this is kind of helpful, I kind of just rambled this out.
- Dens
#153707 - HyperHacker - Fri Apr 04, 2008 5:41 am
Sounds to me like fixed point just means using 1024ths instead of ones. E.g. 2 becomes 2048 because 2048/1024=2. Kinda along the lines of counting in cents instead of dollars.
_________________
I'm a PSP hacker now, but I still <3 DS.
#153709 - DensitY - Fri Apr 04, 2008 6:48 am
HyperHacker wrote: |
Sounds to me like fixed point just means using 1024ths instead of ones. E.g. 2 becomes 2048 because 2048/1024=2. Kinda along the lines of counting in cents instead of dollars. |
yeah, it depends on the format. with the DS you have a few formats
16.16
8.8 (for BG layer coords)
12.4
1.12
24.8
etc
depends on what you need and what the hardware accepts (you'll have to worry about that alot more if you start coding for the 3d hardware).
#153771 - TheMagnitude - Sat Apr 05, 2008 10:34 pm
Thanks guys that helped alot, instead of creating a new topic, does anyone know how to get random numbers with libnds?
#153774 - silent_code - Sun Apr 06, 2008 1:09 am
1) in your titlescreen do: Code: |
#include <stdlib.h> // this is required for random numbers!
...
uint8 r = 0;
while((REG_KEYINPUT & KEY_A) && (REG_KEYINPUT & KEY_START))
{
r++;
swiWaitForVBlank(); // enable vblank before using this!
}
srand(r); //this will make sure that the random number generator will generate different numbers each time the title screen is left |
2) on the nds, there is an rtc (realtime clock), that you can use: Code: |
srand(IPC->time.rtc.seconds); // again, setup the rng, this time with the current second, although you can use anything from the rtc here (and add, multiply, modulo it etc) |
the aforementioned will only work on hw, though. to test if rtc is working, here's some simple time output: Code: |
iprintf("Current time: %2i:%2i.%2i", IPC->time.rtc.hours, IPC->time.rtc.minutes, IPC->time.rtc.seconds); |
after setting up the rng either way, you can obtain a random integer value by using: Code: |
#define randomi(seed) (rand() % seed)
...
...
uint32 rndNr = randomi(1000); |
just an example. hope that's helpful! :^)
happy coding!
#153803 - a128 - Sun Apr 06, 2008 6:55 pm
TheMagnitude wrote: |
Thanks guys that helped alot, instead of creating a new topic, does anyone know how to get random numbers with libnds? |
Mersenne Twister is a good and fast random generator
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html