PostgreSQL Source Code  git master
rint.c File Reference
#include "c.h"
#include <float.h>
#include <math.h>
Include dependency graph for rint.c:

Go to the source code of this file.

Functions

double rint (double x)
 

Function Documentation

◆ rint()

double rint ( double  x)

Definition at line 22 of file rint.c.

Referenced by acquire_inherited_sample_rows(), AdjustFractSeconds(), bernoulli_beginsamplescan(), btcostestimate(), calculatePagesPerBuffer(), cash_div_flt4(), cash_div_flt8(), cash_mul_flt4(), cash_mul_flt8(), check_effective_io_concurrency(), clamp_row_est(), create_modifytable_path(), DecodeInterval(), DecodeNumberField(), dround(), dtoi2(), dtoi4(), dtoi8(), estimate_rel_size(), ExecInitBitmapHeapScan(), final_cost_hashjoin(), final_cost_nestloop(), float4_to_char(), float8_timestamptz(), float8_to_char(), flt4_mul_cash(), flt8_mul_cash(), ftoi2(), ftoi4(), ftoi8(), genericcostestimate(), gincostestimate(), initial_cost_mergejoin(), interval_div(), interval_mul(), make_interval(), make_time(), make_timestamp_internal(), ParseFractionalSecond(), set_append_rel_size(), and system_beginsamplescan().

23 {
24  double x_orig;
25  double r;
26 
27  /* Per POSIX, NaNs must be returned unchanged. */
28  if (isnan(x))
29  return x;
30 
31  if (x <= 0.0)
32  {
33  /* Both positive and negative zero should be returned unchanged. */
34  if (x == 0.0)
35  return x;
36 
37  /*
38  * Subtracting 0.5 from a number very close to -0.5 can round to
39  * exactly -1.0, producing incorrect results, so we take the opposite
40  * approach: add 0.5 to the negative number, so that it goes closer to
41  * zero (or at most to +0.5, which is dealt with next), avoiding the
42  * precision issue.
43  */
44  x_orig = x;
45  x += 0.5;
46 
47  /*
48  * Be careful to return minus zero when input+0.5 >= 0, as that's what
49  * rint() should return with negative input.
50  */
51  if (x >= 0.0)
52  return -0.0;
53 
54  /*
55  * For very big numbers the input may have no decimals. That case is
56  * detected by testing x+0.5 == x+1.0; if that happens, the input is
57  * returned unchanged. This also covers the case of minus infinity.
58  */
59  if (x == x_orig + 1.0)
60  return x_orig;
61 
62  /* Otherwise produce a rounded estimate. */
63  r = floor(x);
64 
65  /*
66  * If the rounding did not produce exactly input+0.5 then we're done.
67  */
68  if (r != x)
69  return r;
70 
71  /*
72  * The original fractional part was exactly 0.5 (since
73  * floor(input+0.5) == input+0.5). We need to round to nearest even.
74  * Dividing input+0.5 by 2, taking the floor and multiplying by 2
75  * yields the closest even number. This part assumes that division by
76  * 2 is exact, which should be OK because underflow is impossible
77  * here: x is an integer.
78  */
79  return floor(x * 0.5) * 2.0;
80  }
81  else
82  {
83  /*
84  * The positive case is similar but with signs inverted and using
85  * ceil() instead of floor().
86  */
87  x_orig = x;
88  x -= 0.5;
89  if (x <= 0.0)
90  return 0.0;
91  if (x == x_orig - 1.0)
92  return x_orig;
93  r = ceil(x);
94  if (r != x)
95  return r;
96  return ceil(x * 0.5) * 2.0;
97  }
98 }