Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 1
/* lround adapted to be llround for Newlib, 2009 by Craig Howland.  */
2
/*
3
 * ====================================================
4
 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5
 *
6
 * Developed at SunPro, a Sun Microsystems, Inc. business.
7
 * Permission to use, copy, modify, and distribute this
8
 * software is freely granted, provided that this notice
9
 * is preserved.
10
 * ====================================================
11
 */
12
 
13
#include "fdlibm.h"
14
 
15
#ifndef _DOUBLE_IS_32BITS
16
 
17
long long int
18
llround(double x)
19
{
20
  __int32_t sign, exponent_less_1023;
21
  /* Most significant word, least significant word. */
22
  __uint32_t msw, lsw;
23
  long long int result;
24
 
25
  EXTRACT_WORDS(msw, lsw, x);
26
 
27
  /* Extract sign. */
28
  sign = ((msw & 0x80000000) ? -1 : 1);
29
  /* Extract exponent field. */
30
  exponent_less_1023 = ((msw & 0x7ff00000) >> 20) - 1023;
31
  msw &= 0x000fffff;
32
  msw |= 0x00100000;
33
 
34
  /* exponent_less_1023 in [-1023,1024] */
35
  if (exponent_less_1023 < 20)
36
    {
37
      /* exponent_less_1023 in [-1023,19] */
38
      if (exponent_less_1023 < 0)
39
        {
40
          if (exponent_less_1023 < -1)
41
            return 0;
42
          else
43
            return sign;
44
        }
45
      else
46
        {
47
          /* exponent_less_1023 in [0,19] */
48
	  /* shift amt in [0,19] */
49
          msw += 0x80000 >> exponent_less_1023;
50
	  /* shift amt in [20,1] */
51
          result = msw >> (20 - exponent_less_1023);
52
        }
53
    }
54
  else if (exponent_less_1023 < (8 * sizeof (long long int)) - 1)
55
    {
56
      /* 64bit longlong: exponent_less_1023 in [20,62] */
57
      if (exponent_less_1023 >= 52)
58
	/* 64bit longlong: exponent_less_1023 in [52,62] */
59
	/* 64bit longlong: shift amt in [32,42] */
60
        result = ((long long int) msw << (exponent_less_1023 - 20))
61
		    /* 64bit longlong: shift amt in [0,10] */
62
                    | (lsw << (exponent_less_1023 - 52));
63
      else
64
        {
65
	  /* 64bit longlong: exponent_less_1023 in [20,51] */
66
          unsigned int tmp = lsw
67
		    /* 64bit longlong: shift amt in [0,31] */
68
                    + (0x80000000 >> (exponent_less_1023 - 20));
69
          if (tmp < lsw)
70
            ++msw;
71
	  /* 64bit longlong: shift amt in [0,31] */
72
          result = ((long long int) msw << (exponent_less_1023 - 20))
73
		    /* ***64bit longlong: shift amt in [32,1] */
74
                    | SAFE_RIGHT_SHIFT (tmp, (52 - exponent_less_1023));
75
        }
76
    }
77
  else
78
    /* Result is too large to be represented by a long long int. */
79
    return (long long int)x;
80
 
81
  return sign * result;
82
}
83
 
84
#endif /* _DOUBLE_IS_32BITS */