Skip to content

Commit 4b37aed

Browse files
AntonioNDavivace
andauthored
Add explanation of converting between floating and fixed point (#21)
* Add explanation of converting between floating and fixed point This is useful in many situations, like when generating fixed point constants, or when printing fixed point values for debugging (or non debugging) purposes. Also, fix some qualifiers (`extern` isn't needed, `const` is nice to use). * Update content/fixed-point-math.md Co-authored-by: Antonio Vivace <avivace4@gmail.com> * Add suggestion --------- Co-authored-by: Antonio Vivace <avivace4@gmail.com>
1 parent 0a9eafc commit 4b37aed

File tree

1 file changed

+54
-5
lines changed

1 file changed

+54
-5
lines changed

content/fixed-point-math.md

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,13 @@ Let's say we have a player sprite, with an X and Y position. What speed should w
111111

112112
```c
113113
// a function elsewhere in code, which needs the ONSCREEN x and y position
114-
extern void display_player(int x, int y);
114+
void display_player(int x, int y);
115115

116116
// player coordinates use signed 28.3f fixed-point format
117-
int player_fp = 3;
117+
const int player_fp = 3;
118118

119119
// 1 and 5/8, written verbosely for demonstration purposes
120-
int player_speed = 8 + 5;
120+
int player_speed = (1 << player_fp) + ((5 << player_fp) / 8);
121121

122122
// let's start the player at (5, 6) on the screen
123123
// shift both of these values left to account for the fixed-point
@@ -163,10 +163,11 @@ Before adding or subtracting fixed-point numbers, you need to make the denominat
163163

164164
```c
165165
// variable 'a' uses an unsigned 27.5f fixed-point format
166-
int a_fp = 5;
166+
const int a_fp = 5;
167167
unsigned int a = 3 << a_fp;
168+
168169
// variable 'b' uses an unsigned 16.16f fixed-point format
169-
int b_fp = 16;
170+
const int b_fp = 16;
170171
unsigned int b = 4 << b_fp;
171172
```
172173

@@ -206,6 +207,54 @@ Even though you can't do hardware-level division, there are usually creative wor
206207

207208
If you really must divide, you would multiply the numerator by the fixed-point first, *before* dividing.
208209

210+
## Converting between fixed and floating point
211+
212+
Now you have a way to do mathematical operations efficiently. How do you set the initial values in a convenient way? How do you print the values in a way that is easier to understand than very big integer values?
213+
214+
Well, you can convert between fixed and floating point easily:
215+
216+
```c
217+
const int player_fp = 3;
218+
219+
static inline int player_float2fixed(float value)
220+
{
221+
return (int)(value * (1 << player_fp));
222+
}
223+
224+
static inline float player_fixed2float(int value)
225+
{
226+
return value / (float)(1 << player_fp);
227+
}
228+
229+
// Macro version of the functions, for situations where you can't use functions
230+
#define PLAYER_FLOAT2FIXED(value) (int)((value) * (1 << (player_fp)))
231+
#define PLAYER_FIXED2FLOAT(value) ((value) / (float)(1 << (player_fp)))
232+
233+
int setup(void)
234+
{
235+
int player_x = player_float2fixed(1.23);
236+
int player_y = PLAYER_FLOAT2FIXED(2.35);
237+
238+
printf("Player X: %f\n", player_fixed2float(player_x);
239+
printf("Player Y: %f\n", PLAYER_FIXED2FLOAT(player_y);
240+
}
241+
```
242+
243+
Remember that those are floating point operations, so they will be slow. There is an exception: if you use `constexpr` or if the compiler detects that an expression is constant, it will calculate it at compile time automatically. This is very useful for setting initial fixed point values from floating point values.
244+
245+
```c
246+
int player_x, player_y;
247+
248+
constexpr int player_start_x = player_float2fixed(1.23); // Only in C++
249+
const int player_start_y = PLAYER_FLOAT2FIXED(2.35);
250+
251+
int setup(void)
252+
{
253+
player_x = player_start_x;
254+
player_y = player_start_y;
255+
}
256+
```
257+
209258
And there you go! You now know everything needed to do fixed-point math. Good luck!
210259

211260
## FAQ

0 commit comments

Comments
 (0)