this repo has no description
1
2/*
3 * lrint.c
4 *
5 * by Ian Ollmann
6 *
7 * Copyright (c) 2007, Apple Inc. All Rights Reserved.
8 *
9 * Implementation of C99 lrint.
10 *
11 * Note that this function contains a bug that will cause values in the
12 * ranges: {LONG_MIN-1 < x < LONG_MIN} and { LONG_MAX-1 < x < LONG_MAX } to
13 * possibly return both inexact and invalid flags, depending on current
14 * rounding mode. This problem only occurs for 32-bit longs. Under LP64,
15 * there are no double precision floating point values in the indicated ranges.
16 *
17 * We couldn't think of a way to get this right in C without extensive use
18 * of fenv functionality, which would slow down the function by many-fold.
19 * A processor-specific version can use the hardware rounding mode sensitive
20 * float to int convert instruction (e.g. fctiw or cvtss2si) here to get the
21 * right answer. Please see the Intel lrint in the regular Libm for sample code.
22 */
23
24#include <math.h>
25
26#if defined(__SOFTFP__)
27
28long lrint( double x )
29{
30 double rounded = round( x );
31 long result = (long)rounded;
32
33 if (__builtin_fabs(result - x) != 0.5)
34 return result;
35 else {
36 // Exact halfway case
37 if (result & 1L) {
38 // If the trailing bit is set, we rounded the wrong way
39 long step = (result >> 30) | 1L;// x < 0 ? -1 : 1
40 return result - step; // x < 0 ? result + 1 : result - 1
41 }
42 else {
43 return result;
44 }
45 }
46}
47
48long lround( double x )
49{
50 return (long)round(x);
51}
52
53#else
54
55#include "d2i.h"
56
57long lrint( double x )
58{
59 return lrint_private( x );
60}
61
62#endif