source: mainline/uspace/lib/math/generic/round.c@ ace1bca4

Last change on this file since ace1bca4 was ace1bca4, checked in by Jiří Zárevúcky <jiri.zarevucky@…>, 7 years ago

Readd round()

  • Property mode set to 100644
File size: 3.2 KB
Line 
1/*
2 * Copyright (c) 2015 Jiri Svoboda
3 * Copyright (c) 2014 Martin Decky
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/** @addtogroup libmath
31 * @{
32 */
33/** @file
34 */
35
36#include <math.h>
37#include <float.h>
38#include <stdint.h>
39
40/**
41 * Rounds its argument to the nearest integer value in floating-point format,
42 * rounding halfway cases away from zero, regardless of the current rounding
43 * direction.
44 */
45float roundf(float val)
46{
47 /* If the input is a nan, return a canonical nan. */
48 if (isnan(val))
49 return __builtin_nanf("");
50
51 const int exp_bias = FLT_MAX_EXP - 1;
52 const int mant_bits = FLT_MANT_DIG - 1;
53
54 union {
55 float f;
56 uint32_t i;
57 } u = { .f = fabsf(val) };
58
59 int exp = (u.i >> mant_bits) - exp_bias;
60
61 /* If value is less than 0.5, return zero with appropriate sign. */
62 if (exp < -1)
63 return copysignf(0.0f, val);
64
65 /* If exponent is exactly mant_bits, adding 0.5 could change the result. */
66 if (exp >= mant_bits)
67 return val;
68
69 /* Use trunc with adjusted value to do the rounding. */
70 return copysignf(truncf(u.f + 0.5), val);
71}
72
73/**
74 * Rounds its argument to the nearest integer value in floating-point format,
75 * rounding halfway cases away from zero, regardless of the current rounding
76 * direction.
77 */
78double round(double val)
79{
80 /* If the input is a nan, return a canonical nan. */
81 if (isnan(val))
82 return __builtin_nan("");
83
84 const int exp_bias = DBL_MAX_EXP - 1;
85 const int mant_bits = DBL_MANT_DIG - 1;
86
87 union {
88 double f;
89 uint64_t i;
90 } u = { .f = fabs(val) };
91
92 int exp = ((int)(u.i >> mant_bits)) - exp_bias;
93
94 /* If value is less than 0.5, return zero with appropriate sign. */
95 if (exp < -1)
96 return copysign(0.0, val);
97
98 /* If exponent is exactly mant_bits, adding 0.5 could change the result. */
99 if (exp >= mant_bits)
100 return val;
101
102 /* Use trunc with adjusted value to do the rounding. */
103 return copysign(trunc(u.f + 0.5), val);
104}
105
106/** @}
107 */
Note: See TracBrowser for help on using the repository browser.