os/ossrv/genericopenlibs/cstdlib/LMATH/S_MODF.C
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/* S_MODF.C
sl@0
     2
 * 
sl@0
     3
 * Portions Copyright (c) 1993-1999 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     4
 * All rights reserved.
sl@0
     5
 */
sl@0
     6
sl@0
     7
sl@0
     8
/* @(#)s_modf.c 5.1 93/09/24 */
sl@0
     9
/*
sl@0
    10
 * ====================================================
sl@0
    11
 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
sl@0
    12
 *
sl@0
    13
 * Developed at SunPro, a Sun Microsystems, Inc. business.
sl@0
    14
 * Permission to use, copy, modify, and distribute this
sl@0
    15
 * software is freely granted, provided that this notice 
sl@0
    16
 * is preserved.
sl@0
    17
 * ====================================================
sl@0
    18
 */
sl@0
    19
sl@0
    20
/*
sl@0
    21
FUNCTION
sl@0
    22
       <<modf>>, <<modff>>---split fractional and integer parts
sl@0
    23
sl@0
    24
INDEX
sl@0
    25
	modf
sl@0
    26
INDEX
sl@0
    27
	modff
sl@0
    28
sl@0
    29
ANSI_SYNOPSIS
sl@0
    30
	#include <math.h>
sl@0
    31
	double modf(double <[val]>, double *<[ipart]>);
sl@0
    32
        float modff(float <[val]>, float *<[ipart]>);
sl@0
    33
sl@0
    34
TRAD_SYNOPSIS
sl@0
    35
	#include <math.h>
sl@0
    36
	double modf(<[val]>, <[ipart]>)
sl@0
    37
        double <[val]>;
sl@0
    38
        double *<[ipart]>;
sl@0
    39
sl@0
    40
	float modff(<[val]>, <[ipart]>)
sl@0
    41
	float <[val]>;
sl@0
    42
        float *<[ipart]>;
sl@0
    43
sl@0
    44
DESCRIPTION
sl@0
    45
	<<modf>> splits the double <[val]> apart into an integer part
sl@0
    46
	and a fractional part, returning the fractional part and
sl@0
    47
	storing the integer part in <<*<[ipart]>>>.  No rounding
sl@0
    48
	whatsoever is done; the sum of the integer and fractional
sl@0
    49
	parts is guaranteed to be exactly  equal to <[val]>.   That
sl@0
    50
	is, if . <[realpart]> = modf(<[val]>, &<[intpart]>); then
sl@0
    51
	`<<<[realpart]>+<[intpart]>>>' is the same as <[val]>.
sl@0
    52
	<<modff>> is identical, save that it takes and returns
sl@0
    53
	<<float>> rather than <<double>> values. 
sl@0
    54
sl@0
    55
RETURNS
sl@0
    56
	The fractional part is returned.  Each result has the same
sl@0
    57
	sign as the supplied argument <[val]>.
sl@0
    58
sl@0
    59
PORTABILITY
sl@0
    60
	<<modf>> is ANSI C. <<modff>> is an extension.
sl@0
    61
sl@0
    62
QUICKREF
sl@0
    63
	modf  ansi pure 
sl@0
    64
	modff - pure
sl@0
    65
sl@0
    66
*/
sl@0
    67
sl@0
    68
/*
sl@0
    69
 * modf(double x, double *iptr) 
sl@0
    70
 * return fraction part of x, and return x's integral part in *iptr.
sl@0
    71
 * Method:
sl@0
    72
 *	Bit twiddling.
sl@0
    73
 *
sl@0
    74
 * Exception:
sl@0
    75
 *	No exception.
sl@0
    76
 */
sl@0
    77
sl@0
    78
#include "FDLIBM.H"
sl@0
    79
sl@0
    80
static const double one = 1.0;
sl@0
    81
sl@0
    82
/**
sl@0
    83
Split floating-point value into fractional and integer parts.
sl@0
    84
Breaks x in two parts: the integer (stored in location pointed by iptr)
sl@0
    85
and the fraction (return value).
sl@0
    86
@return Fractional part of x
sl@0
    87
@param x Floating point value. 
sl@0
    88
@param iptr Location where the integer part of x will be stored.
sl@0
    89
*/	
sl@0
    90
EXPORT_C double modf(double x, double *iptr) __SOFTFP
sl@0
    91
{
sl@0
    92
	__int32_t i0,i1,j0;
sl@0
    93
	__uint32_t i;
sl@0
    94
	EXTRACT_WORDS(i0,i1,x);
sl@0
    95
	j0 = ((i0>>20)&0x7ff)-0x3ff;	/* exponent of x */
sl@0
    96
	if(j0<20) {			/* integer part in high x */
sl@0
    97
	    if(j0<0) {			/* |x|<1 */
sl@0
    98
	        INSERT_WORDS(*iptr,i0&0x80000000,0);	/* *iptr = +-0 */
sl@0
    99
		return x;
sl@0
   100
	    } else {
sl@0
   101
		i = (0x000fffff)>>j0;
sl@0
   102
		if(((i0&i)|i1)==0) {		/* x is integral */
sl@0
   103
		    __uint32_t high;
sl@0
   104
		    *iptr = x;
sl@0
   105
		    GET_HIGH_WORD(high,x);
sl@0
   106
		    INSERT_WORDS(x,high&0x80000000,0);	/* return +-0 */
sl@0
   107
		    return x;
sl@0
   108
		} else {
sl@0
   109
		    INSERT_WORDS(*iptr,i0&(~i),0);
sl@0
   110
		    return x - *iptr;
sl@0
   111
		}
sl@0
   112
	    }
sl@0
   113
	} else if (j0>51) {		/* no fraction part */
sl@0
   114
	    __uint32_t high;
sl@0
   115
	    *iptr = x*one;
sl@0
   116
	    GET_HIGH_WORD(high,x);
sl@0
   117
	    INSERT_WORDS(x,high&0x80000000,0);	/* return +-0 */
sl@0
   118
	    return x;
sl@0
   119
	} else {			/* fraction part in low x */
sl@0
   120
	    i = ((__uint32_t)(0xffffffff))>>(j0-20);
sl@0
   121
	    if((i1&i)==0) { 		/* x is integral */
sl@0
   122
	        __uint32_t high;
sl@0
   123
		*iptr = x;
sl@0
   124
		GET_HIGH_WORD(high,x);
sl@0
   125
		INSERT_WORDS(x,high&0x80000000,0);	/* return +-0 */
sl@0
   126
		return x;
sl@0
   127
	    } else {
sl@0
   128
	        INSERT_WORDS(*iptr,i0,i1&(~i));
sl@0
   129
		return x - *iptr;
sl@0
   130
	    }
sl@0
   131
	}
sl@0
   132
}