[comp.lang.c] MSC 4.0 and Floating Point problem

paul@devon.UUCP (Paul Sutcliffe Jr.) (09/12/87)

I am having trouble with math accuracy while developing a program
under MSC 4.0 (using MS-DOS 3.20).  Here is the problem:

I have some numbers stored in character arrays, and some stored as
longs.  I need to perform some math on these numbers, and store the
result in a long.  For example, let's say I have:

char factor1[7];
char factor2[7];
...
char amount1[7];
char amount2[7];
...
long value1;
long value2;
...

I need to perform the formula:

	result1 = (factor1 * value1) + amount1
	result2 = (factor2 * value2) + amount2

and so on.  I wrote a small "test program" to try to pinpoint the
problem.  Here is the program:

#include <stdio.h>
#include <math.h>

main()
{
	long result;
	long amount = 85000L;
	char *f = ".01500";
	char *a = "100   ";

	result = (long)(atof(f) * (double)amount) + atol(a);
	printf("result = %ld\n", result);
}

My calculator tells me that "(0.01500 * 85000) + 100" is equal to 1375.
But compiling the above program produces the message:

result = 1374

Not correct!  My intention was to have the multiplication performed
with "double"'s (atof is declared as a double in math.h), cast the
result into a long, add the second long (atol(a)), producing the
result.  Further testing proved that I could obtain the correct answer
by using the "/FPa" compiler option, which loads the "alternate" math
library, without changing the above program.

The default library (/FPi) and the /FPc library both produced the bad
answer.  I do not have an 8087 chip in my system, so using the alternate
library does not affect me.  However, in the "real-world", the system
running this program may have a math co-processor.

Does the /FPa library preclude the use of the 80x87, if found?  The
/FPi and /FPc libraries are supposed to load the emulator, but use
the 80x87 if it exists.  Is there a bug in the MSC floating point
emulator?

Responses by e-mail, please.  I'll summarize to the net.

- paul
-- 
Paul Sutcliffe, Jr.

UUCP (smart):  paul@devon.UUCP
UUCP (dumb):   ...{rutgers,ihnp4,cbosgd}!bpa!vu-vlsi!devon!paul

gwyn@brl-smoke.UUCP (09/13/87)

In article <396@devon.UUCP> paul@devon.UUCP (Paul Sutcliffe Jr.) writes:
>I am having trouble with math accuracy while developing a program

Welcome to the wonderful world of floating-point arithmetic!

>	result = (long)(atof(f) * (double)amount) + atol(a);

The problem is that the product is inexact (due to the nature
of floating-point), and by casting to (long) you truncate it
rather than round it to the nearest integer.  If the product
is known to be nonnegative, add 0.5 to it before casting.