aboutsummaryrefslogtreecommitdiff
path: root/arch/all/core/include/float.h
blob: 6f65fa8d1e7aa70b18b0ea424f9f98d67d4330f0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/* ****************************************************************************
 * float.h -- Floating constants.
 * Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
 *
 * This file is part of the 'all/core' module,
 * in libcarrot, an experimental modular libc project.
 *
 * This file is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation, either version 3 of the License, or (at your option)
 * any later version.
 *
 * This file is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Lesser Public
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this file.  If not, see <http://www.gnu.org/licenses/>.
 * ************************************************************************* */
#include <cdefs.h>
#include_bits <types.h>

/* A floating-point number (x), according to the ISO C99 standard,
 * is defined by the following model:
 *
 *		x = s * b^e *  Σ {1 ≤ k ≤ n} (f_k * b^(-k))
 *
 * - `s` is the sign exponent (0 or 1);
 * - `b` is the base or radix of exponent representation (an integer > 1);
 * - `e` is the exponent (an integer between `e_min` and `e_max`);
 * - `p` is the precision (number of base-`b` digits in the significand);
 * - `f_k` are the nonnegative integers less than `b` (the significand digits).
 *
 * There are two "types" for floating-point numbers, depending on the size
 * of their fields:
 * - 32-bits floating-point numbers, also called single-precision or binary32;
 * - 64-bits floating-point numbers, also called double-precision or binary64.
 *
 * Among the constants are:
 * - `MANT_DIG`: number of base `FLT_RADIX` digits in the significand, p;
 * - `SINGLE_DIG`: the number of decimal digits, q, such that any
 *   floating-point number with q decimal digits can be rounded into a
 *   floating-point number with p radix b digits and back again without change
 *   to the q decimal digits;
 * - `MIN_EXP`: the minimum integer x such that FLT_RADIX^(x - 1)
 *   is a normalized float, emin.
 * - `MAX_EXP`: the maximum integer x such that FLT_RADIX^(x - 1)
 *   is a representable float, emax.
 * - `MIN_10_EXP`: the minimum negative integer such that 10 raised to that
 *   power is in the range of normalized floating-point numbers;
 * - `MAX_10_EXP`: the maximum positive integer such that 10 raised to that
 *   power is in the range of representable finit floating-point numbers;
 * - `MIN`: the minimum normalized positive floating-point number;
 * - `MAX`: the maximum representable finite floating-point number;
 * - `EPSILON`: the difference between 1 and the least value greater than 1
 *   that is representable in the given floating-point type.
 *
 * `SINGLE_DIG` is either:
 *
 *		p * log10(b)               if b is a power of 10,
 *		floor((p - 1) * log10(b))  otherwise.
 *
 * `MIN_10_EXP` is:
 *
 *		ceil(log10(b) * (emin - 1))
 *
 * `MAX_10_EXP` is:
 *
 *		floor(log10((1 - b**p) * b*emax))
 *
 * `MIN` is:
 *
 *		b ** (emin - 1)
 *
 * `MAX` is:
 *
 *		(1 - b**(-p)) * b**emax
 *
 * `EPSILON` is:
 *
 *		(b ** 1) - p
 */

#define __FLT_SINGLE_MANT_DIG 24
#define __FLT_DOUBLE_MANT_DIG 53

#define __FLT_SINGLE_DIG  6
#define __FLT_DOUBLE_DIG 15

#define __FLT_SINGLE_MIN_EXP (-125)
#define __FLT_DOUBLE_MIN_EXP (-1021)

#define __FLT_SINGLE_MIN_10_EXP (-37)
#define __FLT_DOUBLE_MIN_10_EXP (-307)

#define __FLT_SINGLE_MAX_EXP 128
#define __FLT_DOUBLE_MAX_EXP 1024

#define __FLT_SINGLE_MAX_10_EXP 38
#define __FLT_DOUBLE_MAX_10_EXP 308

#define __FLT_SINGLE_MAX 3.4028234663852886e+38F
#define __FLT_DOUBLE_MAX 1.7976931348623157e+308L

#define __FLT_SINGLE_EPSILON 1.1920928955078125e-7
#define __FLT_DOUBLE_EPSILON 2.2204460492503131e-16

#define __FLT_SINGLE_MIN 1.1754943508222875e-38
#define __FLT_DOUBLE_MIN 2.2250738585072014e-308

/* Addition rounds to 0: zero, 1: nearest, 2: +inf, 3: -inf, -1: unknown.
 * FIXME: this is supposed to change with calls to `fsetround` in <fenv.h> */

#define __FLT_ROUNDS 1

#if __USE_C99
/* The floating-point expression evaluation method.
 *   -1  indeterminate
 *    0  evaluate all operations and constants just to the range and
 *       precision of the type
 *    1  evaluate operations and constants of type float and double
 *       to the range and precision of the double type, evaluate
 *       long double operations and constants to the range and precision
 *       of the long double type
 *    2  evaluate all operations and constants to the range and precision
 *       of the long double type.
 *
 * FIXME: this ought to change with the setting of the fp control word;
 * the value provided by the compiler assumes the widest setting. */

# define __FLT_EVAL_METHOD __FLT_EVAL_METHOD__

/* Number of decimal digits; n, such that any floating-point number in the
 * widest supported floating type with pmax radix b digits can be rounded to
 * a floating-point number with n decimal digits and back again without
 * change to the value,
 *
 *		pmax * log10(b)            if b is a power of 10
 *		ceil(1 + pmax * log10(b))  otherwise. */

# define __FLT_DECIMAL_DIG __DECIMAL_DIG__
#endif

#if __USE_CXX11

/* Versions of DECIMAL_DIG for each floating-point type. */
/* TODO: finish */

#endif