GNU libc Rounding Functions
See also http://www.gnu.org/software/libc/manual/html_node/Rounding-Functions.html
The functions listed here perform operations such as rounding and truncation
of floating-point values. Some of these functions convert floating point
numbers to integer values. They are all declared in math.h
.
You can also convert floating-point numbers to integers simply by casting
them to int. This discards the fractional part, effectively rounding towards
zero.
However, this only works if the result can actually be represented as an
int-for very large numbers, this is impossible.
The functions listed here return the result as a double instead to get around
this problem.
The fromfp
functions use the following macros, from TS 18661-1:2014, to
specify the direction of rounding.
These correspond to the rounding directions defined in IEEE 754-2008.
trunc
The trunc
functions round x towards zero to the nearest integer
(returned in floating-point format). Thus,
trunc (1.5) is 1.0 and trunc (-1.5) is -1.0 (丢掉小数部分, x 大于等于 0 的时候结果
等于 floor(x), x 小于等于 0 的时候结果等于 ceil(x)).
ceil
These functions round x upwards to the nearest integer, returning that value
as a double. Thus, ceil (1.5) is 2.0 (ceil: 天花板 — 向上(大)取整).
floor
These functions round x downwards to the nearest integer, returning that value
as a double. Thus, floor (1.5) is 1.0 and floor (-1.5) is -2.0 (
floor: 地板 — 向下(小)取整).
round
These functions are similar to rint
, but they round halfway cases(一半的情况)
away from zero instead of to the nearest integer
(or other current rounding mode).
I.e. round to nearest integer, away from zero (返回 四舍五入整数).
rint
These functions round x to an integer value according to the current rounding
mode, usually 1, example 2.23-0ubuntu11
libc, gcc 5.4.0: FLT_ROUNDS
is 1:
/usr/lib/gcc/x86_64-linux-gnu/5/include/float.h:128
:
/* Addition rounds to 0: zero, 1: nearest, 2: +inf, 3: -inf, -1: unknown. */
/* ??? This is supposed to change with calls to fesetround in <fenv.h>. */
#undef FLT_ROUNDS
#define FLT_ROUNDS 1
And:
BUGS
C99 specifies that the value of FLT_ROUNDS should reflect changes
to the current rounding mode, as set by fesetround(). Currently,
this does not occur: FLT_ROUNDS always has the value 1.
Round to nearest integer (Like round
, but maybe NOT good, better use round
when nearest integer, especially “四舍五入”, rint
返回 最接近参数的整数,
如果有两个数同样接近, 则会返回偶数的那个 !!).
Bad rint examples
EXPECT_DOUBLE_EQ(-2.0, ::rint(-1.5));
EXPECT_DOUBLE_EQ(-2.0, ::rint(-2.5));// Here we want -3.0!
EXPECT_DOUBLE_EQ(0.0, ::rint(0.5));// Here we want 1.0!
EXPECT_DOUBLE_EQ(0.0, ::rint(-0.5));// Here we want -1.0!
Good round examples
EXPECT_DOUBLE_EQ(-2.0, ::round(-1.5));
EXPECT_DOUBLE_EQ(-3.0, ::round(-2.5));// Here we want -3.0!
EXPECT_DOUBLE_EQ(1.0, ::round(0.5));// Here we want 1.0!
EXPECT_DOUBLE_EQ(-1.0, ::round(-0.5));// Here we want -1.0!
对比
value | round | rint | floor | ceil | trunc |
---|---|---|---|---|---|
0.1 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 |
0.5 | 1.0 | 0.0 | 0.0 | 1.0 | 0.0 |
0.6 | 1.0 | 1.0 | 0.0 | 1.0 | 0.0 |
1.1 | 1.0 | 1.0 | 1.0 | 2.0 | 1.0 |
1.5 | 2.0 | 2.0 | 1.0 | 2.0 | 1.0 |
2.3 | 2.0 | 2.0 | 2.0 | 3.0 | 2.0 |
2.5 | 3.0 | 2.0 | 2.0 | 3.0 | 2.0 |
3.8 | 4.0 | 4.0 | 3.0 | 4.0 | 3.0 |
5.5 | 6.0 | 6.0 | 5.0 | 6.0 | 5.0 |
-0.5 | -1.0 | -0.0 | -1.0 | -0.0 | -0.0 |
-1.1 | -1.0 | -1.0 | -2.0 | -1.0 | -1.0 |
-1.5 | -2.0 | -2.0 | -2.0 | -1.0 | -1.0 |
-2.3 | -2.0 | -2.0 | -3.0 | -2.0 | -2.0 |
-2.5 | -3.0 | -2.0 | -3.0 | -2.0 | -2.0 |
-3.8 | -4.0 | -4.0 | -4.0 | -3.0 | -3.0 |
-5.5 | -6.0 | -6.0 | -6.0 | -5.0 | -5.0 |