OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [uClibc/] [libm/] [powerpc/] [s_rint.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1325 phoenix
/*******************************************************************************
2
**      File:   rndint.c
3
**
4
**      Contains: C source code for implementations of floating-point
5
**                functions which round to integral value or format, as
6
**                defined in header <fp.h>.  In particular, this file
7
**                contains implementations of functions rint, nearbyint,
8
**                rinttol, round, roundtol, trunc, modf and modfl.  This file
9
**                targets PowerPC or Power platforms.
10
**
11
**      Written by: A. Sazegari, Apple AltiVec Group
12
**          Created originally by Jon Okada, Apple Numerics Group
13
**
14
**      Copyright: © 1992-2001 by Apple Computer, Inc., all rights reserved
15
**
16
**      Change History (most recent first):
17
**
18
**      13 Jul 01  ram  replaced --setflm calls with inline assembly
19
**      03 Mar 01  ali  first port to os x using gcc, added the crucial __setflm
20
**                      definition.
21
**                              1. removed double_t, put in double for now.
22
**                              2. removed iclass from nearbyint.
23
**                              3. removed wrong comments intrunc.
24
**                              4.
25
**      13 May 97  ali  made performance improvements in rint, rinttol, roundtol
26
**                      and trunc by folding some of the taligent ideas into this
27
**                      implementation.  nearbyint is faster than the one in taligent,
28
**                      rint is more elegant, but slower by %30 than the taligent one.
29
**      09 Apr 97  ali  deleted modfl and deferred to AuxiliaryDD.c
30
**      15 Sep 94  ali  Major overhaul and performance improvements of all functions.
31
**      20 Jul 94  PAF  New faster version
32
**      16 Jul 93  ali  Added the modfl function.
33
**      18 Feb 93  ali  Changed the return value of fenv functions
34
**                      feclearexcept and feraiseexcept to their new
35
**                      NCEG X3J11.1/93-001 definitions.
36
**      16 Dec 92  JPO  Removed __itrunc implementation to a
37
**                      separate file.
38
**      15 Dec 92  JPO  Added __itrunc implementation and modified
39
**                      rinttol to include conversion from double
40
**                      to long int format.  Modified roundtol to
41
**                      call __itrunc.
42
**      10 Dec 92  JPO  Added modf (double) implementation.
43
**      04 Dec 92  JPO  First created.
44
**
45
*******************************************************************************/
46
 
47
#include <limits.h>
48
#include <math.h>
49
 
50
#define      SET_INVALID      0x01000000UL
51
 
52
typedef union
53
      {
54
      struct {
55
#if defined(__BIG_ENDIAN__)
56
        unsigned long int hi;
57
        unsigned long int lo;
58
#else
59
        unsigned long int lo;
60
        unsigned long int hi;
61
#endif
62
      } words;
63
      double dbl;
64
      } DblInHex;
65
 
66
static const unsigned long int signMask = 0x80000000ul;
67
static const double twoTo52      = 4503599627370496.0;
68
static const double doubleToLong = 4503603922337792.0;              // 2^52
69
static const DblInHex Huge       = {{ 0x7FF00000, 0x00000000 }};
70
static const DblInHex TOWARDZERO = {{ 0x00000000, 0x00000001 }};
71
 
72
/*******************************************************************************
73
*                                                                              *
74
*     The function rint rounds its double argument to integral value           *
75
*     according to the current rounding direction and returns the result in    *
76
*     double format.  This function signals inexact if an ordered return       *
77
*     value is not equal to the operand.                                       *
78
*                                                                              *
79
********************************************************************************
80
*                                                                              *
81
*     This function calls:  fabs.                                                  *
82
*                                                                              *
83
*******************************************************************************/
84
 
85
/*******************************************************************************
86
*     First, an elegant implementation.                                        *
87
********************************************************************************
88
*
89
*double rint ( double x )
90
*      {
91
*      double y;
92
*
93
*      y = twoTo52.fval;
94
*
95
*      if ( fabs ( x ) >= y )                          // huge case is exact
96
*            return x;
97
*      if ( x < 0 ) y = -y;                            // negative case
98
*      y = ( x + y ) - y;                              // force rounding
99
*      if ( y == 0.0 )                                 // zero results mirror sign of x
100
*            y = copysign ( y, x );
101
*      return ( y );
102
*      }
103
********************************************************************************
104
*     Now a bit twidling version that is about %30 faster.                     *
105
*******************************************************************************/
106
 
107
double rint ( double x )
108
      {
109
      DblInHex argument;
110
      register double y;
111
      unsigned long int xHead;
112
      register long int target;
113
 
114
      argument.dbl = x;
115
      xHead = argument.words.hi & 0x7fffffffUL;          // xHead <- high half of |x|
116
      target = ( argument.words.hi < signMask );         // flags positive sign
117
 
118
      if ( xHead < 0x43300000ul )
119
/*******************************************************************************
120
*     Is |x| < 2.0^52?                                                         *
121
*******************************************************************************/
122
            {
123
            if ( xHead < 0x3ff00000ul )
124
/*******************************************************************************
125
*     Is |x| < 1.0?                                                            *
126
*******************************************************************************/
127
                  {
128
                  if ( target )
129
                        y = ( x + twoTo52 ) - twoTo52;  // round at binary point
130
                  else
131
                        y = ( x - twoTo52 ) + twoTo52;  // round at binary point
132
                  if ( y == 0.0 )
133
                        {                               // fix sign of zero result
134
                        if ( target )
135
                              return ( 0.0 );
136
                        else
137
                              return ( -0.0 );
138
                        }
139
                  return y;
140
                  }
141
 
142
/*******************************************************************************
143
*     Is 1.0 < |x| < 2.0^52?                                                   *
144
*******************************************************************************/
145
 
146
            if ( target )
147
                  return ( ( x + twoTo52 ) - twoTo52 ); //   round at binary pt.
148
            else
149
                  return ( ( x - twoTo52 ) + twoTo52 );
150
            }
151
 
152
/*******************************************************************************
153
*     |x| >= 2.0^52 or x is a NaN.                                             *
154
*******************************************************************************/
155
      return ( x );
156
      }
157
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.