[<<Previous Entry]
[^^Up^^]
[Next Entry>>]
[Menu]
[About The Guide]
APPENDIX D - SIMULATED FP MATH
When I was working on my Free disk space program, I could not get
it to link as a Tiny program, no matter what I did. Even if I
compiled it with the Small memory model, it would not run without
65K RAM available. After exhaustive testing, I realized what the
problem was: I was trying to link in Borland's FP Emulation. If
you use FP Emulation, you will NOT be able to generate a .COM
file. This was a significant problem. Who wants a free disk space
program requiring 65K?
Unfortunately, I had but two options: leave out all real math,
which was totally unacceptable, or write my own FP functions. With
great trepidation I wrote a division function which more than fit
my needs. The real division found in the source distributed with
my free program is far simpler than the rdiv() function in TCHK,
fulfilling a far simpler need.
Consider yourself warned right now. My real functions are NOT a
complete substitute for Borland's FP Emulation library. However,
if you only need accuracy up to 8 decimal places for numbers with
integer portions less than 2 billion and change, or plan on using
the Tiny memory model, they are acceptable.
A REAL number is defined as:
typedef struct REAL {
long rint; /* real - integer */
long rfrac; /* real - fraction */
int precision; /* (# of decimal places) */
};
A picture is worth a thousand words, so here are some sample REALs
and the real numbers they represent:
{ 402, 17, 2 } = 402.17
{ 12, 2, 3 } = 12.002
{ 0, 0, 0 } = 0.0
{ -8356, 286, 3 } = -8356.286
{ 0, -3, 1 } = -0.3
REALs obey certain rules:
Sign: If rint is non-zero, it will contain the sign of the
REAL and rfrac will be positive. If rint is zero,
rfrac will contain the sign of the REAL
Precision: always ranging from 0 to MAXPRECISION, it will
NEVER be negative
Decimal: the decimal portion of a REAL is always represented
as a value displayed to the right of the decimal
point. For instance, { 3, 6, 4 } is the REAL
representation of 3.0006, which could also be
expressed as { 3, 0006, 4 }. Note that a long with
a value of 0006 is the same as a long with a value
of 6. It is only because longs are used to store
the value of REALs that the precision plays such a
crucial role
To calculate the value of a REAL, use the following formula:
value = rint + rfrac * 10(-precision)
which is read as "value equals rint plus rfrac times ten raised to
the negative precision power".
Error trapping for such things as division by zero, overflow,
underflow, etc. as listed in REAL.H is provided.
Planned for some future release is a facility for a user-defined
rmatherr() function, much like Borland's facility for a user-
-defined matherr(), and a method of handling larger (> LONG_MAX)
numbers, probably through the use of negative precision values.
Perhaps at an even later date there will be a true set of real
math functions, done the right way with mantissas and exponents
via bit encoding. This would require a significant amount of
effort, since I would basically be rewriting Borland's EMU.LIB, so
don't get your hopes up too high. With sufficient user response or
personal need, I may give it a shot. However, due to the great
complexity of such a project, you will understand if I don't rush
right out and whip up said emulation functions.
See Also:
radd()
rdiv()
rfloor()
rnegate()
rnormalize()
rsign()
This page created by ng2html v1.05, the Norton guide to HTML conversion utility.
Written by Dave Pearson