// 15 August 1997, Rick Huebner:  Small changes made to adapt for MathLib

/* @(#)s_rint.c 5.1 93/09/24 */
/*
 * ====================================================
 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
 *
 * Developed at SunPro, a Sun Microsystems, Inc. business.
 * Permission to use, copy, modify, and distribute this
 * software is freely granted, provided that this notice
 * is preserved.
 * ====================================================
 */

/*
 * rint(x)
 * Return x rounded to integral value according to the prevailing
 * rounding mode.
 * Method:
 *	Using floating addition.
 * Exception:
 *	Inexact flag raised if x not equal to rint(x).
 */

#include "..\Math.h"


#if defined(__BORLANDC__)
#pragma warn -8041
#endif

tDouble math_rint(tDouble x)
/***********************************************************************
 *
 *	math_rint
 *
 ***********************************************************************/
{
tDouble TWO52[2] = {	 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
											-4.50359962737049600000e+15 /* 0xC3300000, 0x00000000 */ };
tDouble w,t;
tLong i0,j0,sx;
tULong i,i1;
	
	EXTRACT_WORDS(i0,i1,x);
	
	// Récupèrer le signe
	sx = (i0 >> 31) & 1;			
	
	// Récupèrer la mantisse
	j0 = ((i0 >> 20) & 0x7ff) - 0x3ff;	
	
	if (j0 < 20)
	{
	  if (j0 < 0)
	  {
			if (((i0 & 0x7fffffff) | i1) == 0) 
				return x;
			
			i1 |= (i0 & 0x0fffff);
			i0 &= 0xfffe0000;
			i0 |= ((i1 | -i1) >> 12) & 0x80000;
			
			SET_HIGH_WORD(x, i0);
			
	    w = TWO52[sx] + x;
	    t = w - TWO52[sx];
			
			GET_HIGH_WORD(i0, t);
			SET_HIGH_WORD(t, (i0 & 0x7fffffff) | (sx << 31));
			
	    return t;
	  } 
	  else
	  {
			i = (0x000fffff) >> j0;
			if (((i0 & i) | i1) == 0)  /* x is integral */
				return x;
				
			i >>= 1;
			
			if(((i0 & i) | i1) != 0)
			{
		    if (j0==19) 
		    	i1 = 0x40000000;
		    else
		    	i0 = (i0&(~i))|((0x20000)>>j0);
			}
	  }
	} 
	else if (j0 > 51) 
	{
	  if (j0 == 0x400) 	
	  	return x+x; /* inf or NaN */
	  else 
	  	return x;		/* x is integral */
	} 
	else 
	{
	  i = ((tULong)(0xffffffff)) >> (j0 - 20);
	  
	  if ((i1 & i) == 0) 
	  	return x;	/* x is integral */
	  	
	  i >>= 1;
	  
	  if ((i1 & i) != 0) 
	  	i1 = (i1 & (~i)) | ((0x40000000) >> (j0 - 20));
	}
	
	INSERT_WORDS(x, i0, i1);
	w = TWO52[sx] + x;
	
	return (w - TWO52[sx]);
}

#if defined(__BORLANDC__)
#pragma warn +8041
#endif

