VOGONS


First post, by radiance32

User metadata
Rank Member
Rank
Member

Hi,

I'm using OpenWatcom 1.9, compiling code for MS DOS that uses the huge memory model,
for a 8086 CPU target.

I am currently in the process of converting the renderloop of my code into fixed point math instead of floating point math,
for better performance on 8086 and up without an FPU present in the machine...

However, all my tests with this code return values of 0.000000
It's very strange...

Could this be some compiler setting I accidentally switched on, or is there a bug in my code ?
I've gone over it many times and can't find a bug...

Here's the code at the top of my project that handles fixed point math (16.16 as 32bit long)
I cobbled it together from some internet blog posts etc...

#define FIXED_TYPE_SIZE long
#define FIXED_POINT_FRACTIONAL_BITS 16 // 32 bits = 16.16


// Choose what floating point values to use as REALs
typedef FIXED_TYPE_SIZE F_REAL; // (Fixed Point Real Number)


// Convert float to fixed-point
F_REAL RTOFIX(float value) {
return (F_REAL)(value * (1 << FIXED_POINT_FRACTIONAL_BITS));
}

// Convert fixed-point to float
float FIXTOR(F_REAL value) {
return (float)value / (1 << FIXED_POINT_FRACTIONAL_BITS);
}

// Convert integer to fixed-point
F_REAL ITOFIX(int value) {
return value << FIXED_POINT_FRACTIONAL_BITS;
}

// Convert fixed-point to integer
int FIXTOI(F_REAL value) {
return value >> FIXED_POINT_FRACTIONAL_BITS;
}

// Multiplication of two fixed-point numbers
F_REAL F_REAL_MUL(F_REAL a, F_REAL b) {
return (F_REAL)(((long long)a * b) >> FIXED_POINT_FRACTIONAL_BITS);
}

// Division of two fixed-point numbers
F_REAL F_REAL_DIV(F_REAL a, F_REAL b) {
return (F_REAL)(((long long)a << FIXED_POINT_FRACTIONAL_BITS) / b);
}

Then I do a simple test:

float a = 5.f;
F_REAL b = RTOFIX(a);
float c = FIXTOR(b);

printf("c = %f\n", c);

Output is: c = 0.000000 !!!
and should be ~5.000000

Is there anyone that can shed some light on this ?

Cheers,
Terrence

Check out my new HP 100/200LX Palmtop YouTube Channel! https://www.youtube.com/channel/UCCVChzZ62a-c4MdJWyRwdCQ

Reply 1 of 2, by Error 0x7CF

User metadata
Rank Member
Rank
Member

Must be an issue with int type sizes, or compiler, same code works fine on gcc targeting x86_64 and 32-bit x86.
I afterwards went through and changed the types to what they *should* be for openwatcom 16bit and it still gave me 5.0000 though, so I'd lean more on the side of compiler.

Old precedes antique.

Reply 2 of 2, by radiance32

User metadata
Rank Member
Rank
Member
Error 0x7CF wrote on 2024-05-06, 02:42:

Must be an issue with int type sizes, or compiler, same code works fine on gcc targeting x86_64 and 32-bit x86.
I afterwards went through and changed the types to what they *should* be for openwatcom 16bit and it still gave me 5.0000 though, so I'd lean more on the side of compiler.

I just figured it out,
I had to change int to long in the conversion routines and use long notation for constants like 12L instead of 12

It's working now 😀
It's still slower than 8087 emulation turned on in dosbox,
but, I've yet to optimize the currently floating point trigonometric functions,
probably using lookup tables...
Also going to try and switch to 16bit 4.12 fixed point, I'll have to normalize my model size, but in theory that should boost speed too...

Thanks for your time anyways,
Terrence

Check out my new HP 100/200LX Palmtop YouTube Channel! https://www.youtube.com/channel/UCCVChzZ62a-c4MdJWyRwdCQ