Page 1 of 1

Floating-point precision issues, or a broken printf?

Posted: Sat Mar 21, 2009 6:06 pm
by 01000101
hey, I recently ported most of (all but the file-system functions) PDPCLib v1.00. From there, I decided to write floating-point support into my printf() [%f]. I seem to have most of it complete, but I'm having some precision problems. I set the FPU control word (verified by bochs debugger) to 80-bit precision and rounding-up.

In Linux, when I use printf("%1.22f\n", (double)0.12345678901234567890) I get about 17 decimal places worth of precision, on mine I get about 7 decimal places of precision. I typecast on both Linux and my OS to (double) to ensure that one isn't using "float" or "long double".

Here's my code for printing the float (and compensate for 2 digits worth of rounding), it's a mish-mash of different OSS/PD code.

Code: Select all

static void print_double(double d, size_t precision) 
{
	double di, df, pr, tmp;
   
	/* if it's zero, just print the '0' and exit */
	if(d == 0.0)
	{ print_char('0'); return; }
	/* if it's a negative integer, print '-' and make the integer absolute */
	else if (d < 0) 
	{
		print_char('-');
		d = fabs(d);
	}
   
	/* break the double into fraction (df) and integer (di) parts */
	df = modf(d, &di);

	/* print the integer portion */
	print_int((size_t)floor(di));

	/* round up if necessary */
	if (df != 0) 
	{ 
		print_char('.');

		pr = df * pow(10, precision+1);
		modf(pr, &pr);
		
		/* we need to extract the last+1 decimal place and see if we should round up */
		while(pr > 10.0){ pr /= 10; }
		/* if it's 4, we should check the next decimal place to see if it's >= 5 */
		if(pr == 4)
		{
			pr = df * pow(10, precision+2);
			modf(pr, &pr);
			while(pr > 10.0){ pr /= 10; }
			if(pr >= 5){ df = df + (0.1 / pow(10, precision)); }
		}
		if(pr >= 5){ df = df + (0.1 / pow(10, precision)); }
	}

	/* calculate the fractional portion to print */
	while (df != 0 && precision--) 
	{
		df = df * 10;
		df = modf(df, &di);

		print_int((int)di);
	}
}
I've tested it with and without the rounding, so I doubt that is the issue (although it is very experimental). I would hope it would not be the floor() or modf() functions as they are part of the PDPCLib.

Any ideas?

Re: Floating-point precision issues, or a broken printf?

Posted: Mon Mar 23, 2009 9:10 pm
by bewing
Well, since nobody else seems to be replying to this, I guess I will say one little thing. I've looked at the code a little, and it seems OK. However, getting 7 significant digits on a supposedly double-precision equation is almost always a sign that one of the operands has only been calculated as a single-precision float. As far as I can tell, all the function calls you made should return good doubles. However, I'm going to bet that within one of those functions, some variable or function call is only a float. So, yes, I'm figuring the error is in the library. If you have any opportunity, this is exactly the kind of error that singlestepping through the code (including the library sourcecode) will locate quickly.

Re: Floating-point precision issues, or a broken printf?

Posted: Mon Mar 23, 2009 11:31 pm
by 01000101
Thanks for replying.

I haven't got around to single-stepping through the library calls (it's on the ToDo list), but I'm starting to trust this library less and less the more I look into it. I recently found out that the log() function gets stuck in an endless while loop (and I don't have the mathematical expertise to figure out why). I'll probably end up ditching this library (PDPClib) in favor of a more well-known/tested library (uClibc probably).

I'll report back once I get around to debugging the function calls.

Re: Floating-point precision issues, or a broken printf?

Posted: Tue Mar 24, 2009 11:04 am
by bewing
Doesn't Solar's C library have all this stuff in it?

Re: Floating-point precision issues, or a broken printf?

Posted: Tue Mar 24, 2009 11:46 am
by Combuster
Floating point stuff is pretty much absent. There's no math.h (there is in my edited version) and *printf doesn't have floating point support.

Re: Floating-point precision issues, or a broken printf?

Posted: Tue Mar 24, 2009 1:03 pm
by 01000101
bewing wrote:Doesn't Solar's C library have all this stuff in it?
unfortunately not.
Combuster wrote:Floating point stuff is pretty much absent. There's no math.h (there is in my edited version) and *printf doesn't have floating point support.
There's a lot of integrated mathematical functions that need to be written for even the most basic of %f/g format support.

I'm currently trying to get uClibc setup with my OS, but it's not going well. It has a very nice set of math functions that I'd like to be able to use.

Re: Floating-point precision issues, or a broken printf?

Posted: Wed Mar 25, 2009 3:35 am
by Solar
bewing wrote:Doesn't Solar's C library have all this stuff in it?
Erm... nope. :oops:

It took me about a year to churn out Freestanding, <string.h> and <stdlib.h>, and I was quite confident I could continue at that rate.

Then I screwed up my first attempt at <stdio.h>, got two kids, played WoW more than was good for me (and my family), and eventually, inherited a house that was in dire need of a complete overhaul which we are still in the aftermath of.

I.e., no I/O, no locale, wide char, time, or math support in PDCLib, yet.

I am (again) hoping for the Breakpoint weekend (Easter, you heathens!), to re-ignite my productivity. And I am so fed up with being stuck in <stdio.h> for three years that I am willing to take two weeks of vacation afterwards just to get this &$%&ยง thing done. :evil:

Re: Floating-point precision issues, or a broken printf?

Posted: Wed Mar 25, 2009 4:10 am
by Combuster
wide char
I implemented a bunch of that since I needed it for the freebasic runtime, if you want to have it... (my server's down atm, so I'll mail it if you want it)

Re: Floating-point precision issues, or a broken printf?

Posted: Wed Mar 25, 2009 7:48 am
by Solar
None of the stuff is missing because I can't do it, it's missing because a) it's reserved for a later step (do one thing at a time) and b) I didn't have the time to get to that step yet.

But thanks for the offer.