> I have a coule of books on 3d programming, most of which say that
>fixed point math is a good way to optimise any program (although none
>of them actually tell me how), But I heard that on a pentium floating
>point math is much faster, and the books are quite old. So, is it
>worth going to all the trouble of learning how to use fixed point
>math, or is it now redundant.
Nope, fixed-point math is still VERY fast, and if you're going to create
somewhat fast 3D-engine you should intensively use it.
Of course, floating-point math is worth of attention for non-time critical
moments or when you use pairing for performing slow floating point division
while performing integer operations, so you get division for free.
A floating-point number is simply a 32-bit integer, most often in 16.16
format
for common computations (mean last 16 bits is for fractional part of number)
the C macros to convert from / to fixedpoint are:
------Fixed.h--------------
typedef long int32;
typedef long Fixedpoint;
#define INT_TO_FIXED(x) ((int32)x << 16)
#define FIXED_TO_INT(x) ((int32)x >> 16)
#define DOUBLE_TO_FIXED(x) ((int32)(x*65536.0+0.5))
#define FIXED_TO_DOUBLE(x) ((double)x/65536.0)
--------------------
In special cases you might be in need of different type of fixedpoint number
:
[8.24] for greater precision or [24.8] for greater range of numbers
represented
This also would be helpful in assembler routines when you select the
division to integer/fractional parts for the best performance...
In C, to perform addition / subtraction of fixedpoint values, simply write
Fixedpoint a, b, c, d;
c = a + b;
d = a - b;
To perform multiplication / division, use the following code:
-------Fixed.h ----------
extern "C" Fixedpoint FixedMul (Fixedpoint M1, Fixedpoint M2);
extern "C" Fixedpoint FixedDiv (Fixedpoint Dividdend, Fixedpoint Divisor);
------- Fixed.asm ------- (32-bit protected mode)
.486p
.model flat
public FixedMul
public FixedDiv
ROUNDING_ON equ 1 ; set to 0 to disable rounding (1 bit loss / 1 cycle
faster)
.code
align dword
FMparms struc
dd 2 dup (?)
FMm1 dd ?
FMm2 dd ?
FMparms ends
;+-------------------------------------------------------------------
;| Fixedpoint FixedMul (Fixedpoint m1, Fixedpoint m2);
;+-------------------------------------------------------------------
FixedMul proc
push ebp
mov ebp, esp
mov eax,[ebp+FMm1]
imul [ebp+FMm2]
if ROUNDING_ON
add eax,8000h
adc edx,0
endif
shrd eax, edx, 16
pop ebp
ret
FixedMul endp
FDparms struc
dd 2 dup(?)
Dividend dd ?
Divisor dd ?
FDparms ends
;+-----------------------------------------------------------------+
;| Fixedpoint FixedDiv (Fixedpoint Dividend, Fixedpoint Divisor); |
;+-----------------------------------------------------------------+
FixedDiv proc
push ebp
mov ebp, esp
mov ebx, [ebp+Divisor]
mov eax, [ebp+Dividend]
cdq
shld edx, eax, 16
shl eax, 16
idiv ebx
pop ebp
ret
FixedDiv endp
end
--------------------
Hope that would help you to get used to loving fixedpoint math... :))
If have questions, feel free to mail me
CU
--
***> http://qdamage.webjump.com <*** collection of my demos / sources ***