Subject: Re: accuracy of "long double"
To: Neil Booth <neil@daikokuya.co.uk>
From: Matthias Drochner <M.Drochner@fz-juelich.de>
List: tech-toolchain
Date: 08/20/2007 15:17:52
This is a multipart MIME message.

--==_Exmh_34042622989200
Content-Type: text/plain; charset=us-ascii


neil@daikokuya.co.uk said:
> b) Exponents have a wider range, so overflows or underflows that
>    would happen on doubles don't necessarily happen on long
>    doubles.

Yes, I had figured that too, see my second reply to the PR.

> d) Despite many claims to the contrary that you will read on the
>    net, and on GCC lists, there is no double-rounding problem.

The famous "paranoia" test program finds a number of rounding
flaws eg on Linux. I've extracted the failing tests for
multiplication - see attachment.
The tests succeed on NetBSD. If I set the FPCW to its initial
value, ie 64-bit rounding (by enabling the "#if 0" part),
the tests fail. With -mfpmath=sse, the tests succeed.
So doubles are still not rounded correctly if the FPU is used
in extended precision mode.

best regards
Matthias




-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
Forschungszentrum Juelich GmbH
52425 Juelich

Sitz der Gesellschaft: Juelich
Eingetragen im Handelsregister des Amtsgerichts Dueren Nr. HR B 3498
Vorsitzende des Aufsichtsrats: MinDirig'in Baerbel Brumme-Bothe
Vorstand: Prof. Dr. Achim Bachem (Vorsitzender), Dr. Ulrich Krafft (stellv. 
Vorsitzender)
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------

--==_Exmh_34042622989200
Content-Type: text/plain ; name="para_part.c"; charset=us-ascii
Content-Description: para_part.c
Content-Disposition: attachment; filename="para_part.c"

#include <stdio.h>
#include <float.h>

#define FLOAT double
#define EPSILON DBL_EPSILON

FLOAT Zero = 0.0, One = 1.0, OneAndHalf = 1.5;
FLOAT T, X, Y, Y1, Y2, Z;
FLOAT U2 = EPSILON; /* probed in "paranoia" */

int
mult1()
{

	Y2 = One + U2;
	X = OneAndHalf - U2;
	Z = (X - U2) * Y2;
	Z = Z - X;
	return (Z == Zero);
}

int
mult2()
{

	Y1 = One - U2;
	X = OneAndHalf - U2;
	Y = OneAndHalf + U2;
	T = Y * Y1;
	T = T - X;
	return (T <= Zero);
}

int
main()
{
#if 0
        const int fpcw = 0x37f;
        asm("fldcw %0"::"m"(fpcw));
#endif
	if (!mult1())
		printf("* rounding error 1\n");
	if (!mult2())
		printf("* rounding error 2\n");
	return 0;
}

--==_Exmh_34042622989200--