source: mainline/uspace/lib/math/generic/trunc.c@ ed9043f7

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

Strip libmath to the bare necessities

  • Property mode set to 100644
File size: 3.7 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/** Truncate fractional part (round towards zero)
41 *
42 * Truncate the fractional part of IEEE 754 single
43 * precision floating point number by zeroing fraction
44 * bits, effectively rounding the number towards zero
45 * to the nearest whole number.
46 *
47 * If the argument is infinity or NaN, an exception
48 * should be indicated. This is not implemented yet.
49 *
50 * @param val Floating point number.
51 *
52 * @return Number rounded towards zero.
53 *
54 */
55float truncf(float val)
56{
57 /* If the input is a nan, return a canonical nan. */
58 if (isnan(val))
59 return __builtin_nanf("");
60
61 const int exp_bias = FLT_MAX_EXP - 1;
62 const int mant_bits = FLT_MANT_DIG - 1;
63 const uint32_t mant_mask = (UINT32_C(1) << mant_bits) - 1;
64
65 union {
66 float f;
67 uint32_t i;
68 } u = { .f = fabsf(val) };
69
70 int exp = (u.i >> mant_bits) - exp_bias;
71
72 /* If value is less than one, return zero with appropriate sign. */
73 if (exp < 0)
74 return copysignf(0.0f, val);
75
76 if (exp >= mant_bits)
77 return val;
78
79 /* Truncate irrelevant fraction bits */
80 u.i &= ~(mant_mask >> exp);
81 return copysignf(u.f, val);
82}
83
84/** Truncate fractional part (round towards zero)
85 *
86 * Truncate the fractional part of IEEE 754 double
87 * precision floating point number by zeroing fraction
88 * bits, effectively rounding the number towards zero
89 * to the nearest whole number.
90 *
91 * If the argument is infinity or NaN, an exception
92 * should be indicated. This is not implemented yet.
93 *
94 * @param val Floating point number.
95 *
96 * @return Number rounded towards zero.
97 *
98 */
99double trunc(double val)
100{
101 /* If the input is a nan, return a canonical nan. */
102 if (isnan(val))
103 return __builtin_nan("");
104
105 const int exp_bias = DBL_MAX_EXP - 1;
106 const int mant_bits = DBL_MANT_DIG - 1;
107 const uint64_t mant_mask = (UINT64_C(1) << mant_bits) - 1;
108
109 union {
110 double f;
111 uint64_t i;
112 } u = { .f = fabs(val) };
113
114 int exp = ((int)(u.i >> mant_bits)) - exp_bias;
115
116 /* If value is less than one, return zero with appropriate sign. */
117 if (exp < 0)
118 return copysign(0.0, val);
119
120 if (exp >= mant_bits)
121 return val;
122
123 /* Truncate irrelevant fraction bits */
124 u.i &= ~(mant_mask >> exp);
125 return copysign(u.f, val);
126}
127
128/** @}
129 */
Note: See TracBrowser for help on using the repository browser.