Fixed point and trig functions

Started by
17 comments, last by frob 16 years, 4 months ago
I want to write a software renderer for my cellphone and I've read up on fixed point math, but how would I apply this to a fixed point number such as 0.5? The sin of 5 and .5 is different so how does that work?
Advertisement
Fixed point trig functions work pretty much the same as manual calculation of non-fixed point trig functions. The traditional method is to first map the angle into the range -PI to PI or 0 to 2*PI (depending on the trig function) and then apply a Taylor/Maclaurin expansion. For example, the expansion of sin(x) around 0 is x - x3/3! + x5/5! - x7/7! + x9/9! .... Just apply the number of terms necessary for the precision of your number.
Ah, I see. I was actually thinking about the built in functions in the math libraries but now that I think about it that won't work at all. So if I want to go 90 degrees, that's 0.5*PI so using that number I should get close to 1 right?

I'm not sure if I have the calculation right. Would it be something like:
0.5PI = 1.57 so as a 32 bit fixed point number it would be (in 16.16 precision), 65536 + (57 << 15) and then I would plug that into the sin approx function?
Actually SiCrane has no clue what he is talking about. Trigs and all other functions (with exception of *low* degree polynomial) are implemented through lookup tables in fixed point libraries. You can download nokia Symbian OS 3d game example from forum.nokia.com It includes trigs and atrigs implementation through lookup tables. Idea is simple - precalculate table of 256 points for 0 - PI/2 quadrant. After that downshift your value to 0-1024 range, get quadrant and get value from table. IF you need more precision get more points.
Quote:Original post by serg3d
Actually SiCrane has no clue what he is talking about. Trigs and all other functions (with exception of *low* degree polynomial) are implemented through lookup tables in fixed point libraries. You can download nokia Symbian OS 3d game example from forum.nokia.com It includes trigs and atrigs implementation through lookup tables. Idea is simple - precalculate table of 256 points for 0 - PI/2 quadrant. After that downshift your value to 0-1024 range, get quadrant and get value from table. IF you need more precision get more points.


The lookup table is merely an optimisation - how do you think you fill out those tables to begin with?

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Using a lookup table for fixed point stuff is the way to go. It will also be faster than using the taylor expansion. To compute this lookup table you can simply use the standard math functions and convert the result to a fixed point library.

I have already developed a software renderer which uses fixed point math. You might want to check it out. On my homepage you will also find a small fixed point math library which contains functions for sin() and cos() in fixed point 16.16 format.
Quote:Original post by Trenki
To compute this lookup table you can simply use the standard math functions and convert the result to a fixed point library.

Which is great if you're on a platform which supports floating point. For the situation the OP is talking about, you need the Taylor expansion.
Quote:Original post by Sneftel
Quote:Original post by Trenki
To compute this lookup table you can simply use the standard math functions and convert the result to a fixed point library.

Which is great if you're on a platform which supports floating point. For the situation the OP is talking about, you need the Taylor expansion.


Did you actually do any non-trivial fixed point coding? Fought register overflow and rounding error? Do you have any idea how to calculate Sum x^i/i! for 16 or even 10 bit fixed point with [0., 1.]->[0->2^10] representation ? To actually do it you have to simulate floating point, including sum, multiplication and division operations. Just trying to do it easy way with multiplication-downshift will get you into world of hurt. More easy would be just drop complete 256 element hard coded array into code.

Quote:Original post by serg3d
Did you actually do any non-trivial fixed point coding? Fought register overflow and rounding error?
For years and years, so drop the attitude.
Quote:Do you have any idea how to calculate Sum x^i/i! for 16 or even 10 bit fixed point with [0., 1.]->[0->2^10] representation ? To actually do it you have to simulate floating point, including sum, multiplication and division operations.
Er, I suppose you could do it that way, but much more simple and efficient (and probably more accurate) is simply to do it in simulated 32-bit fixed point, interleaving the multiplications and divisions to keep the appropriate range.
Quote:Original post by Sneftel
Quote:Original post by Trenki
To compute this lookup table you can simply use the standard math functions and convert the result to a fixed point library.

Which is great if you're on a platform which supports floating point. For the situation the OP is talking about, you need the Taylor expansion.


Sneftel, you are wrong on this one. You really don't want to use the taylor expansion. You can precompute the lookup table on whatever computer you want and use it everywhere. You can even precompute the lookup table on hardware which does not support floating point in hardware. It would still work as the standard C library is required to support the float and double types and also the functions like sin, cos etc. Take the GP2X for example. You can use floats from C/C++ but then they will be emulated since the GP2X does not have native hardware support for floating point, but you can still use them, so it would also be possible to compute the lookup table at runtime, but normally you would compute it offline and store it in some source file.

This topic is closed to new replies.

Advertisement