/*********************************************************************\
d1mach: Ascend Replacement for d1mach.f
by Ben Allan
Created: September, 1994
Version: $Revision: 1.3 $
Date last modified: $Date: 1998/07/06 10:56:12 $
This file is part of the Ascend fortran subroutine collection.
Copyright (C) Benjamin Andrew Allan
The ascend fortran subroutine collection is free software; you can redistribute
it and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
Most of the sources in the ascend fortran subroutine collection are public
domain and available from NETLIB. See newsgroup sci.math.numerical-analysis.
Sources from netlib are not restricted by the GNU license and are marked as
such.
The Ascend fortran subroutine collection is distributed in hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License along with
the program; if not, write to the Free Software Foundation, Inc., 675
Mass Ave, Cambridge, MA 02139 USA. Check the file named COPYING.
COPYING is found in ../compiler.
\*********************************************************************/
/* d1mach.c. Ben Allan
C replacement for d1mach.f in terms of ANSI constants.
The LINPACK d1mach.f is not such that f77 compilers pick
the right set of constants automatically.
Observed equivalences:
F D1MACH( 1) = B**(EMIN-1), THE SMALLEST POSITIVE MAGNITUDE.
C DBL_MIN
F D1MACH( 2) = B**EMAX*(1 - B**(-T)), THE LARGEST MAGNITUDE.
C DBL_MAX
F D1MACH( 3) = B**(-T), THE SMALLEST RELATIVE SPACING.
C DBL_EPSILON/2
F D1MACH( 4) = B**(1-T), THE LARGEST RELATIVE SPACING.
C DBL_EPSILON
F D1MACH( 5) = LOG10(B)
C NONE
B: FLT_RADIX
EMIN: DBL_MIN_EXP
EMAX: DBL_MAX_EXP
T: DBL_MANT_DIG
On alphas d1mach(3)=DBL_EPSILON/2 for some reason. Returning
DBL_EPSILON may result in 1 bit of conservatism in some codes, but
this is the price of portability.
*/
#include
#include
#include
#include
/* Commentary and Apology:
* We used to have a bunch of #ifdef's here trying to figure out which
* platform we were on and then blessing our d1mach function with the
* proper number of underbars (d1mach vs d1mach_) so that the linker
* would not whine about missing symbols due to the insanity of
* whether or not the f77 compiler puts an underbar on the symbols it
* generates. Of course, just to make life fun, it's not strictly
* platform dependent, since some f77 compilers accept flags that turn
* the underbars on or off. Given this lunacy and the wasted time of
* trying to tack down this bug every time it occurs, we've decided to
* just duplicate the function and be finished with the underbar
* madness. We realize this sucks and we apologize for it, but at
* this point,``Frankly, my dears, we don't give a damn.''
*/
double d1mach(int *i) {
switch (*i) {
case 1:
return DBL_MIN;
case 2:
return DBL_MAX;
case 3:
return DBL_EPSILON;
case 4:
return DBL_EPSILON;
case 5:
return log10((double)FLT_RADIX);
default:
fprintf(stderr," D1MACH - I OUT OF BOUNDS %d",*i);
abort();
}
}
double d1mach_(int *i) {
return d1mach(i);
}
double D1MACH(int *i) {
return d1mach(i);
}