# Floating point faster than fixed-point

This is a discussion on Floating point faster than fixed-point within the A Brief History of Cprogramming.com forums, part of the Community Boards category; Yeah, I know - sounds stupid, but it's true. I'm still perfecting my voxel engine. One huge problem was that ...

1. ## Floating point faster than fixed-point

Yeah, I know - sounds stupid, but it's true.

I'm still perfecting my voxel engine. One huge problem was that it requires quite a few linear and bi-linear interpolations. My first thought, stop using floats and switch to fixed point. So, I did that.
However my frame rate in 320x200x64K was near abysmal. Also, the viewing distance was not satisfactory.

Function 1 - fixed point
Code:
```int LI(int v1,int v2,long f1)
{
return v1+(f1*(v2-v1)>>SHIFT);
}```
Function 2 - double
Code:
```int LI(int v1,int v2,double f1)
{
return (int)((double)v1+(double)f1*((double)v2-(double)v1));
}```
Even with all of the typecasting (just to be sure, ugly but ensures correct result) function 2 is faster than 1.

Function 3 - inline asm for FPU
Code:
```int LI(int v1,int v2,double f1)
{
int value=0;
asm
{
finit               //init FPU - just to be sure
fild v2         //place v2 on FPU stack
fisub v1      //integer subtract v1
fmul f1        //real multiply f1
fistp value  //store integer in value, pop ST
}
return value;
}```
Function 3 is the fastest of these three. I even tried using fixed point in assembly, but since inline does not allow 32-bit registers, it was tedious and slower. Not sure if fixed point in 32-bit registers is faster. Someone with MASM, please try this out and let me know.

At least for inline asm, it looks like goodbye to fixed point. Never thought I would be saying that.

Still too slow for 640x480x64K, because of all of the bank switching. Protected mode would allow much faster bank switch or even linear frame buffer, but my copy of DJGPP got eaten by a virus.

Would like to see some DJGPP code for VBE 2.0+.

2. > but since inline does not allow 32-bit registers
I find this hard to believe, what do you think the compiler uses?

Try using eax instead of ax

> Yeah, I know - sounds stupid, but it's true.
Well if you're reading decade old graphics tutorials, then it certainly was the case that fixed point was faster than floating point (especially if your floating point was a library, and not a co-processor).

Co-processors are both very fast, and very pipelined, and run in parallel to the main processor.

There's a wide variety of choice out there processor-wise, and what's good for one might not be so good for another. Which is why I would avoid any assembler unless it becomes absolutely necessary, and you've exhausted all other techniques.

And a fair few of the optimisation tricks you should also be treated with suspision as well. Compiler optimisation has come a long way.

3. No, my inline will not accept eax. I'm using old BC 4.52. Have not been able to get my hands on new BCB yet.

I know this is all old, but I'm just tinkering in DOS till I get something that will do DirectX and COM.

http://www.easystreet.com/~jkirwan/pctools.html

5. ID (makers of Doom & Quake) themselves went to floating point using the MathCo way back when they made Quake 1. The Co-processor was just so much faster since it was built into Pentiums than the old separate ones or emulation, and it's easier to program than fixed point math. One trick they still employ to make things even faster is to calculate often used numbers, such as the Sine of all numbers 0 thru 360, and store them in a quick look-up table before the game starts.

6. I've already pre-computed distance tables and sin/cos/tan tables. Also have used more angles based on screen width to smoothen out the render.

Yeah, the FPU is much faster than fixed point. But there are still recently dated tutorials that still cling to the idea that fixed point is faster than the FPU. It's just not true.

I'm glad the FPU is quicker because it is so easy to program and you don't have all of the shifting and mutliplies in your code. Fixed point code is so hard to read, even when it is in my own source.

Most of my renderer is now in assembly so I'm considering writing the entire procedure in MASM or TASM as my C code is getting rather ugly. I'm also going to port it to protected mode to get rid of that crazy bank switch that is far too slow for anything above 320x200x16M.