Category : C Source Code
Archive   : CEPHES22.ZIP
Filename : FLOOR.C

 
Output of file : FLOOR.C contained in archive : CEPHES22.ZIP
/* ceil()
* floor()
* frexp()
* ldexp()
*
* Floating point numeric utilities
*
*
*
* SYNOPSIS:
*
* double x, y;
* double ceil(), floor(), frexp(), ldexp();
* int expnt, n;
*
* y = floor(x);
* y = ceil(x);
* y = frexp( x, &expnt );
* y = ldexp( x, n );
*
*
*
* DESCRIPTION:
*
* All four routines return a double precision floating point
* result.
*
* floor() returns the largest integer less than or equal to x.
* It truncates toward minus infinity.
*
* ceil() returns the smallest integer greater than or equal
* to x. It truncates toward plus infinity.
*
* frexp() extracts the exponent from x. It returns an integer
* power of two to expnt and the significand between 0.5 and 1
* to y. Thus x = y * 2**expn.
*
* ldexp() multiplies x by 2**n.
*
* These functions are part of the standard C run time library
* for many but not all C compilers. The ones supplied are
* written in C for either DEC or IEEE arithmetic. They should
* be used only if your compiler library does not already have
* them.
*
* The IEEE versions assume that denormal numbers are implemented
* in the arithmetic. Some modifications will be required if
* the arithmetic has abrupt rather than gradual underflow.
*/


/*
Cephes Math Library Release 2.1: December, 1988
Copyright 1984, 1987, 1988 by Stephen L. Moshier
Direct inquiries to 30 Frost Street, Cambridge, MA 02140
*/


#include "mconf.h"
#define DENORMAL 1

#ifdef UNK
char *unkmsg = "ceil(), floor(), frexp(), ldexp() must be rewritten!\n";
#endif

#ifdef DEC
#define EXPMSK 0x807f
#define MEXP 255
#define NBITS 56
#endif

#ifdef IBMPC
#define EXPMSK 0x800f
#define MEXP 0x7ff
#define NBITS 53
#endif

#ifdef MIEEE
#define EXPMSK 0x800f
#define MEXP 0x7ff
#define NBITS 53
#endif

extern double MAXNUM;





double ceil(x)
double x;
{
double y;
double floor();

#ifdef UNK
mtherr( "ceil", DOMAIN );
return(0.0);
#endif

y = floor(x);
if( y < x )
y += 1.0;
return(y);
}




/* Bit clearing masks: */

static unsigned short bmask[] = {
0xffff,
0xfffe,
0xfffc,
0xfff8,
0xfff0,
0xffe0,
0xffc0,
0xff80,
0xff00,
0xfe00,
0xfc00,
0xf800,
0xf000,
0xe000,
0xc000,
0x8000,
0x0000,
};




double floor(x)
double x;
{
unsigned short *p;
double y;
int e, i;

#ifdef UNK
mtherr( "floor", DOMAIN );
return(0.0);
#endif

y = x;
/* find the exponent (power of 2) */
#ifdef DEC
p = (unsigned short *)&y;
e = (( *p >> 7) & 0377) - 0201;
p += 3;
#endif

#ifdef IBMPC
p = (unsigned short *)&y + 3;
e = (( *p >> 4) & 0x7ff) - 0x3ff;
p -= 3;
#endif

#ifdef MIEEE
p = (unsigned short *)&y;
e = (( *p >> 4) & 0x7ff) - 0x3ff;
p += 3;
#endif

if( e < 0 )
{
if( y < 0.0 )
return( -1.0 );
else
return( 0.0 );
}

e = (NBITS -1) - e;
/* clean out 16 bits at a time */
while( e >= 16 )
{
#ifdef IBMPC
*p++ = 0;
#endif

#ifdef DEC
*p-- = 0;
#endif

#ifdef MIEEE
*p-- = 0;
#endif
e -= 16;
}

/* clear the remaining bits */
if( e > 0 )
*p &= bmask[e];

if( (x < 0) && (y != x) )
y -= 1.0;

return(y);
}



double frexp( x, pw2 )
double x;
int *pw2;
{
double y;
int i, k;
short *q;

y = x;

#ifdef UNK
mtherr( "frexp", DOMAIN );
return(0.0);
#endif

#ifdef IBMPC
q = (short *)&y + 3;
#endif

#ifdef DEC
q = (short *)&y;
#endif

#ifdef MIEEE
q = (short *)&y;
#endif

/* find the exponent (power of 2) */
#ifdef DEC
i = ( *q >> 7) & 0377;
if( i == 0 )
{
*pw2 = 0;
return(0.0);
}
i -= 0200;
*pw2 = i;
*q &= 0x807f; /* strip all exponent bits */
*q |= 040000; /* mantissa between 0.5 and 1 */
return(y);
#endif

#ifdef IBMPC
i = ( *q >> 4) & 0x7ff;
if( i != 0 )
goto ieeedon;
#endif

#ifdef MIEEE
i = *q >> 4;
i &= 0x7ff;
if( i != 0 )
goto ieeedon;
#if DENORMAL

#else
*pw2 = 0;
return(0.0);
#endif

#endif


#ifndef DEC
/* Number is denormal or zero */
#if DENORMAL
if( y == 0.0 )
{
iszero:
*pw2 = 0;
return( 0.0 );
}


/* Handle denormal number. */
do
{
y *= 2.0;
i -= 1;
k = ( *q >> 4) & 0x7ff;
}
while( k == 0 );
i = i + k;
#endif /* DENORMAL */

ieeedon:

i -= 0x3fe;
*pw2 = i;
*q &= 0x800f;
*q |= 0x3fe0;
return( y );
#endif
}






double ldexp( x, pw2 )
double x;
int pw2;
{
double y;
short *q;
int e;

#ifdef UNK
mtherr( "ldexp", DOMAIN );
return(0.0);
#endif

y = x;
#ifdef DEC
q = (short *)&y;
e = ( *q >> 7) & 0377;
if( e == 0 )
return(0.0);
#else

#ifdef IBMPC
q = (short *)&y + 3;
#endif
#ifdef MIEEE
q = (short *)&y;
#endif
while( (e = (*q & 0x7ff0) >> 4) == 0 )
{
if( y == 0.0 )
{
return( 0.0 );
}
/* Input is denormal. */
if( pw2 > 0 )
{
y *= 2.0;
pw2 -= 1;
}
if( pw2 < 0 )
{
if( pw2 < -53 )
return(0.0);
y /= 2.0;
pw2 += 1;
}
if( pw2 == 0 )
return(y);
}
#endif /* not DEC */

e += pw2;

/* Handle overflow */
if( e > MEXP )
{
return( MAXNUM );
}

/* Handle denormalized results */
if( e < 1 )
{
#if DENORMAL
if( e < -53 )
return(0.0);
*q &= 0x800f;
*q |= 0x10;
while( e < 1 )
{
y /= 2.0;
e += 1;
}
return(y);
#else
return(0.0);
#endif
}
else
{
#ifdef DEC
*q &= 0x807f; /* strip all exponent bits */
*q |= (e & 0xff) << 7;
#else
*q &= 0x800f;
*q |= (e & 0x7ff) << 4;
#endif
return(y);
}
}


  3 Responses to “Category : C Source Code
Archive   : CEPHES22.ZIP
Filename : FLOOR.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/