Date: Thu, 06 Mar 2008 16:17:40 -0800 From: Colin Percival <cperciva@freebsd.org> To: Bruce Evans <bde@freebsd.org> Cc: cvs-src@freebsd.org, src-committers@freebsd.org, cvs-all@freebsd.org Subject: Re: cvs commit: src/sys/i386/include _types.h Message-ID: <47D089A4.4060208@freebsd.org> In-Reply-To: <20080307085031.P10724@delplex.bde.org> References: <200803051121.m25BLE03035426@repoman.freebsd.org> <20080305182531.GS68971@server.vk2pj.dyndns.org> <20080306021222.GA46783@zim.MIT.EDU> <47CF5D19.3090100@freebsd.org> <20080306033246.GA47280@zim.MIT.EDU> <47CF7EBF.6000009@freebsd.org> <20080306063452.GB48339@zim.MIT.EDU> <47CF9586.70707@freebsd.org> <20080307085031.P10724@delplex.bde.org>
next in thread | previous in thread | raw e-mail | index | archive | help
Bruce Evans wrote: > On Wed, 5 Mar 2008, Colin Percival wrote: >> David Schultz wrote: >>> On Wed, Mar 05, 2008, Colin Percival wrote: >>>> Yes and no. Double rounding isn't allowed; >>> >>> Yes, it is. >> >> No, it isn't. The following code > > Yes it is :-). Extra precision for intermediate values implies double > rounding for the final results, and extra precision for intermediate > values is a fundamental part of C (it used to be only that float > expressions were (de-facto standard required to be) evaluated in double > precision, but now it affects double expressions too, and C99 has vast > complications to support i387'-ish extra precision. Let me clarify: Double rounding isn't allowed by IEEE754. To quote from the October 5th draft of IEEE 754R (which I happen to have in front of me right now): 5.1 Overview All conforming implementations of this standard shall provide the operations listed in this clause for all supported floating-point formats available for arithmetic. Each of the computational operations that return a numeric result specified by this standard shall be performed as if it first produced an intermediate result correct to infinite precision and with unbounded range, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ and then rounded that intermediate result to fit in the destination’s format ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This is clarified further in clause 10: 10.1 Expression evaluation rules Clause 5 of this standard specifies the result of a single arithmetic operation going to an explicit destination. Every operation has an explicit or implicit destination. One rounding occurs to fit the exact result into a ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ destination format. That result is reproducible in that the same operation ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ applied to the same operands under the same attributes produces the same ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ result on all conforming implementations in all languages. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Programming language standards might define syntax for expressions that combine one or more operations of this standard, producing a result to fit an explicit or implicit final destination. When a variable with a declared format ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ is a final destination, as in format conversion to a variable, that declared ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ format of that variable governs its rounding. The format of an implicit ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ destination, or of an explicit destination without a declared format, is defined by language standard expression evaluation rules. In other words, in the code double x, y, z; z = x * y + 1.0; it is perfectly legal for (x * y) to be computed with extra precision; but in the code double x, y, z; z = x * y; z = z - 1.0; both the multiplication and the subtraction must be rounded *once* to double precision. > In C, with FLT_EVAL_METHOD = 2 (evaluate all FP expressions in the range > and precision of the long double type) [...] As someone wrote earlier, the authors of C99 were a bit confused. I can only assume that they intended to be IEEE754-compliant and the rules concerning FLT_EVAL_METHOD apply to *implicit* destinations only. >>> It's impossible to implement efficient library functions that >>> produce correct long double results >> >> You could have stopped this sentence here -- for all practical purposes, >> correctly rounded trigonometric functions are not feasible. > > Nah, it's quite feasible, especially for transcendental functions since > transcendental numbers in general can be approximated more closely by > rationals than algebraic numbers. In fact, one of the common ways to prove that a real number is transcendental is to show that it can be approximated more closely by rationals than any algebraic function can be. > The evaluation just needs to be > done in extra precision How much extra precision do you need? If the exact value of a transcendental function is extremely close to halfway between two consecutive floating-point values, how do you decide which way to round it? Computing transcendental functions to within (0.5+x)ulp for small positive values of x is certainly feasible, but computing provably correctly rounded transcendental functions is very very hard. >> Fortunately, library functions aren't required to have any particular >> error bounds. > > We require error bounds of < 1 ulp and aim for < 0.5[0]1 ulps. What standard states that those bounds are required (or can be relied upon when proving that code is correct)? Intel FPUs over the years have been variously documented to compute transcendental functions to within 1.0, 2.5, or 3.5 ulp -- are you saying that the 8087 doesn't comply with the standard which it inspired? Colin Percival
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?47D089A4.4060208>