xref: /openbsd-src/regress/lib/libm/fpaccuracy/header.h (revision 2b0358df1d88d06ef4139321dd05bd5e05d91eaf)
1*2b0358dfSmartynas /*	$OpenBSD: header.h,v 1.1 2009/04/09 01:24:43 martynas Exp $	*/
2*2b0358dfSmartynas 
3*2b0358dfSmartynas /*
4*2b0358dfSmartynas  * Copyright (c) 2009 Gaston H. Gonnet <gonnet@inf.ethz.ch>
5*2b0358dfSmartynas  *
6*2b0358dfSmartynas  * Permission to use, copy, modify, and distribute this software for any
7*2b0358dfSmartynas  * purpose with or without fee is hereby granted, provided that the above
8*2b0358dfSmartynas  * copyright notice and this permission notice appear in all copies.
9*2b0358dfSmartynas  *
10*2b0358dfSmartynas  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11*2b0358dfSmartynas  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12*2b0358dfSmartynas  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13*2b0358dfSmartynas  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14*2b0358dfSmartynas  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15*2b0358dfSmartynas  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16*2b0358dfSmartynas  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*2b0358dfSmartynas  */
18*2b0358dfSmartynas 
19*2b0358dfSmartynas /* C program to test the accuracy of a given function.
20*2b0358dfSmartynas    This will be done in terms of ulps.  A ulp is a "unit in
21*2b0358dfSmartynas    the last place".  No program can guarantee results better
22*2b0358dfSmartynas    than 0.5 ulp.  As a matter of fact, 0.5 ulp could require
23*2b0358dfSmartynas    infinite computation.  So very good implementations
24*2b0358dfSmartynas    usually achieve 0.51 ulp.  0.6 ulp is still very good, 1 ulp
25*2b0358dfSmartynas    starts to get a bit sloppy.
26*2b0358dfSmartynas 
27*2b0358dfSmartynas    The model of computation is the standard one, the result of f(x)
28*2b0358dfSmartynas    is the correctly rounded value of f(x) when x is assumed to be
29*2b0358dfSmartynas    an exact rational.
30*2b0358dfSmartynas 
31*2b0358dfSmartynas    This program selects values which are difficult to compute to
32*2b0358dfSmartynas    measure the quality of the computation.
33*2b0358dfSmartynas 
34*2b0358dfSmartynas    Hardware which has floating point registers with extra bits of
35*2b0358dfSmartynas    precision (e.g. Pentium) usually do much better than others.
36*2b0358dfSmartynas    This function computes the accuracy for both cases.   */
37*2b0358dfSmartynas 
38*2b0358dfSmartynas /* We represent double precision floating point numbers x as a
39*2b0358dfSmartynas    pair of an integer and a base 2 exponent.  x = mant*2^expo,
40*2b0358dfSmartynas    or x = scalb(mant,expo).  2^52 <= mant < 2^53.  This is to
41*2b0358dfSmartynas    avoid sloppy compilers which do not transcribe correctly
42*2b0358dfSmartynas    some input doubles */
43*2b0358dfSmartynas 
44*2b0358dfSmartynas /* scalb( F(arg[i]), val_e[i] ) == val[i]+eps[i]
45*2b0358dfSmartynas 	to about twice precision.
46*2b0358dfSmartynas 	The scaling is done so that val[i] is in ulps
47*2b0358dfSmartynas 	(val is consequently an integer)
48*2b0358dfSmartynas 	and to avoid underflows in certain cases. */
49*2b0358dfSmartynas 
50*2b0358dfSmartynas /* Shell sort, needs the definition of KEY(x)
51*2b0358dfSmartynas    From: Gonnet & Baeza, Hanbook of Algorithms and Data structures, 4.1.4.
52*2b0358dfSmartynas    Can sort any array r from r[lo] to r[hi] in place.
53*2b0358dfSmartynas    Uses a temporary variable t, of the same type as r[].
54*2b0358dfSmartynas    The comparison is done between KEY(r[i]) vs KEY(r[j]),
55*2b0358dfSmartynas 	so the macro KEY(x) has to be defined appropriately */
56*2b0358dfSmartynas #define SORT(r,lo,up,t) \
57*2b0358dfSmartynas      { int SORTd, SORTi, SORTj; \
58*2b0358dfSmartynas      for ( SORTd=(up)-(lo)+1; SORTd>1; ) { \
59*2b0358dfSmartynas 	  SORTd = SORTd<5 ? 1 : (5*SORTd-1)/11; \
60*2b0358dfSmartynas 	  for ( SORTi=(up)-SORTd; SORTi>=(lo); SORTi-- ) { \
61*2b0358dfSmartynas 	       (t) = (r)[SORTi]; \
62*2b0358dfSmartynas 	       for ( SORTj=SORTi+SORTd; SORTj<=(up) && KEY((t)) > KEY((r)[SORTj]); SORTj+=SORTd ) \
63*2b0358dfSmartynas 		    (r)[SORTj-SORTd] = (r)[SORTj]; \
64*2b0358dfSmartynas 	       (r)[SORTj-SORTd] = (t); \
65*2b0358dfSmartynas 	       } \
66*2b0358dfSmartynas 	  }}
67*2b0358dfSmartynas 
68*2b0358dfSmartynas double scalb( double x, double n );
69