Sin table and fixed point arithmetic in C

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

Post Reply
User avatar
wonder
Posts: 23
Joined: Sat Aug 31, 2019 2:12 pm

Sin table and fixed point arithmetic in C

Post by wonder » Sun Nov 03, 2019 6:16 am

Hi!

I've been trying to understand how to implement fixed point arithmetic in C, but I can't wrap my head around it.
Are there any specific C tutorials around?

I'd like to start experimenting with a sine table (an analog clock demo, for example) but I'm kinda lost without decimals.
One possible approach would be working with values 100x larger and divide them to obtain the x,y pixel values.
Of course, for performance reasons, instead of 100x, I would actually use a power of 2.

I guess that would work, but I would still like to learn how to do fixed-point arithmetic in C on the NES.

As always, many thanks in advance! :)
Image

tepples
Posts: 21750
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Sin table and fixed point arithmetic in C

Post by tepples » Sun Nov 03, 2019 6:46 am

Using values 256 times larger is indeed how fixed point is usually done. While someone else digs up tutorials, you could read through "Fixed-point arithmetic" on Wikipedia.

User avatar
dougeff
Posts: 2614
Joined: Fri May 08, 2015 7:17 pm
Location: DIGDUG
Contact:

Re: Sin table and fixed point arithmetic in C

Post by dougeff » Sun Nov 03, 2019 1:30 pm

I guess you want to convert an angle into X and Y coordinates with a fixed length.

You could actually make your own table of answers, and just use it as a look up table. That would be the typical 1980s way to do it.

But, if you want to know how to do it with fixed point and multiplication, you would make your own tables by multiplying 256 by the sine value of each angle. sine and cosine answers, from 0 to 256, where 256 represents 1.00.

So length radius is Z. Angle is A. All signed int16, fixed point 8.8. Shift Z right 8 to make it 8 bit. Then multiply THAT by the 0-256 sine table to get a 16 bit answer...(fixed point 8.8) the upper 8 bits being the answer you want...so shift right 8 again to get an 8 bit final answer for X and Y.

X = ((Z >> 8) * cos_table[A] ) >> 8;
Y = ((Z >> 8) * sin_table[A] ) >> 8;

I think that's right. I didn't test it.
nesdoug.com -- blog/tutorial on programming for the NES

Pokun
Posts: 1269
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: Sin table and fixed point arithmetic in C

Post by Pokun » Sun Nov 03, 2019 2:34 pm

I explained fixed math arithmetic in a simple way with a practical example once here. Maybe it clicks after reading different people's explanations. This is for binary fixed point though, something which is very useful for game programming even today.

User avatar
Memblers
Site Admin
Posts: 3770
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Re: Sin table and fixed point arithmetic in C

Post by Memblers » Sun Nov 03, 2019 4:49 pm

8.8 fixed point in C is as simple as using 16-bit values for the calculations, and when you're ready to use the result, right shift it 8 times. cc65 in that case is smart enough to simply do LDA highbyte instead of doing any actual bit shifting.

User avatar
wonder
Posts: 23
Joined: Sat Aug 31, 2019 2:12 pm

Re: Sin table and fixed point arithmetic in C

Post by wonder » Mon Nov 04, 2019 5:05 am

Hi guys!

Thank you for the fast replies! :)

@Memblers, @dougeff
So let me see if I'm on the right track:

Code: Select all

static int velocity_x;

void update() {
    // if it was a float: velocity_x += 0.1f;
    velocity_x += ???
    position_x += velocity_x >> 8;
}
Assuming the code is correct, what goes on the ??? mark?
Image

User avatar
NOOPr
Posts: 64
Joined: Tue Feb 27, 2018 10:41 am
Location: Brazil
Contact:

Re: Sin table and fixed point arithmetic in C

Post by NOOPr » Mon Nov 04, 2019 6:47 am

@wonder , just do a rule of three:

Code: Select all

+------------+-------------+
| real value | fixed point |
+------------+-------------+
| 1.0        | 256         |
| 0.5        | 128         |
| 0.1        | 26          |
+------------+-------------+

User avatar
wonder
Posts: 23
Joined: Sat Aug 31, 2019 2:12 pm

Re: Sin table and fixed point arithmetic in C

Post by wonder » Mon Nov 04, 2019 7:08 am

NOOPr wrote:@wonder , just do a rule of three:

Code: Select all

+------------+-------------+
| real value | fixed point |
+------------+-------------+
| 1.0        | 256         |
| 0.5        | 128         |
| 0.1        | 26          |
+------------+-------------+
Thanks @NOOPr!! :beer:
Wow, the solution was so simple I almost feel ashamed of asked such a question in the first place. :oops: :roll:
I think I understand the concept pretty well now. :)

Now I wonder if there would be a pre-processor macro that would to that at compile time... probably not.

Code: Select all

REAL2FIXED(0.5); // outputs 128
Image

User avatar
dougeff
Posts: 2614
Joined: Fri May 08, 2015 7:17 pm
Location: DIGDUG
Contact:

Re: Sin table and fixed point arithmetic in C

Post by dougeff » Mon Nov 04, 2019 8:56 am

Acceleration speed is a trial and error thing that needs to be play tested.
nesdoug.com -- blog/tutorial on programming for the NES

Post Reply