]> gcc.gnu.org Git - gcc.git/blame - gcc/sreal.c
Update copyright years.
[gcc.git] / gcc / sreal.c
CommitLineData
fd27ffab 1/* Simple data type for real numbers for the GNU compiler.
5624e564 2 Copyright (C) 2002-2015 Free Software Foundation, Inc.
ac5e69da
JZ
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
9dcd6f09 8Software Foundation; either version 3, or (at your option) any later
ac5e69da
JZ
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
9dcd6f09
NC
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
ac5e69da 19
fd27ffab 20/* This library supports real numbers;
ac5e69da
JZ
21 inf and nan are NOT supported.
22 It is written to be simple and fast.
23
24 Value of sreal is
25 x = sig * 2 ^ exp
46c5ad27 26 where
ac5e69da
JZ
27 sig = significant
28 (for < 64-bit machines sig = sig_lo + sig_hi * 2 ^ SREAL_PART_BITS)
29 exp = exponent
30
618b7f29 31 One uint64_t is used for the significant.
ac5e69da
JZ
32 Only a half of significant bits is used (in normalized sreals) so that we do
33 not have problems with overflow, for example when c->sig = a->sig * b->sig.
618b7f29 34 So the precision is 32-bit.
46c5ad27 35
ac5e69da
JZ
36 Invariant: The numbers are normalized before and after each call of sreal_*.
37
38 Normalized sreals:
39 All numbers (except zero) meet following conditions:
40 SREAL_MIN_SIG <= sig && sig <= SREAL_MAX_SIG
46c5ad27 41 -SREAL_MAX_EXP <= exp && exp <= SREAL_MAX_EXP
ac5e69da
JZ
42
43 If the number would be too large, it is set to upper bounds of these
44 conditions.
45
46 If the number is zero or would be too small it meets following conditions:
47 sig == 0 && exp == -SREAL_MAX_EXP
48*/
49
50#include "config.h"
51#include "system.h"
bc1c9c22 52#include <math.h>
ac5e69da 53#include "coretypes.h"
ac5e69da
JZ
54#include "sreal.h"
55
ac5e69da
JZ
56/* Print the content of struct sreal. */
57
58void
618b7f29 59sreal::dump (FILE *file) const
ac5e69da 60{
618b7f29 61 fprintf (file, "(%" PRIu64 " * 2^%d)", m_sig, m_exp);
ac5e69da
JZ
62}
63
7b3b6ae4 64DEBUG_FUNCTION void
d1704358 65debug (const sreal &ref)
7b3b6ae4 66{
618b7f29 67 ref.dump (stderr);
7b3b6ae4
LC
68}
69
70DEBUG_FUNCTION void
d1704358 71debug (const sreal *ptr)
7b3b6ae4
LC
72{
73 if (ptr)
74 debug (*ptr);
75 else
76 fprintf (stderr, "<nil>\n");
77}
78
618b7f29
TS
79/* Shift this right by S bits. Needed: 0 < S <= SREAL_BITS.
80 When the most significant bit shifted out is 1, add 1 to this (rounding).
81 */
7b3b6ae4 82
618b7f29
TS
83void
84sreal::shift_right (int s)
ac5e69da 85{
fd27ffab
ML
86 gcc_checking_assert (s > 0);
87 gcc_checking_assert (s <= SREAL_BITS);
41374e13
NS
88 /* Exponent should never be so large because shift_right is used only by
89 sreal_add and sreal_sub ant thus the number cannot be shifted out from
90 exponent range. */
fd27ffab 91 gcc_checking_assert (m_exp + s <= SREAL_MAX_EXP);
ac5e69da 92
618b7f29 93 m_exp += s;
ac5e69da 94
d1704358 95 m_sig += (int64_t) 1 << (s - 1);
618b7f29 96 m_sig >>= s;
ac5e69da
JZ
97}
98
618b7f29 99/* Return integer value of *this. */
ac5e69da 100
618b7f29
TS
101int64_t
102sreal::to_int () const
ac5e69da 103{
d1704358 104 int64_t sign = m_sig < 0 ? -1 : 1;
fd27ffab 105
618b7f29 106 if (m_exp <= -SREAL_BITS)
ac5e69da 107 return 0;
618b7f29 108 if (m_exp >= SREAL_PART_BITS)
fd27ffab 109 return sign * INTTYPE_MAXIMUM (int64_t);
618b7f29 110 if (m_exp > 0)
d1704358 111 return m_sig << m_exp;
618b7f29 112 if (m_exp < 0)
d1704358
ML
113 return m_sig >> -m_exp;
114 return m_sig;
ac5e69da
JZ
115}
116
2bef63e1
JH
117/* Return value of *this as double.
118 This should be used for debug output only. */
119
120double
121sreal::to_double () const
122{
123 double val = m_sig;
124 if (m_exp)
125 val *= exp2 (m_exp);
126 return val;
127}
128
618b7f29 129/* Return *this + other. */
ac5e69da 130
618b7f29
TS
131sreal
132sreal::operator+ (const sreal &other) const
ac5e69da 133{
fd27ffab 134 int dexp;
d1704358
ML
135 sreal tmp, r;
136
137 const sreal *a_p = this, *b_p = &other, *bb;
fd27ffab 138
8301b194 139 if (a_p->m_exp < b_p->m_exp)
fd27ffab
ML
140 std::swap (a_p, b_p);
141
618b7f29
TS
142 dexp = a_p->m_exp - b_p->m_exp;
143 r.m_exp = a_p->m_exp;
ac5e69da
JZ
144 if (dexp > SREAL_BITS)
145 {
618b7f29 146 r.m_sig = a_p->m_sig;
ac5e69da
JZ
147 return r;
148 }
149
150 if (dexp == 0)
618b7f29 151 bb = b_p;
ac5e69da
JZ
152 else
153 {
618b7f29
TS
154 tmp = *b_p;
155 tmp.shift_right (dexp);
ac5e69da
JZ
156 bb = &tmp;
157 }
158
618b7f29
TS
159 r.m_sig = a_p->m_sig + bb->m_sig;
160 r.normalize ();
ac5e69da
JZ
161 return r;
162}
163
d1704358 164
618b7f29 165/* Return *this - other. */
ac5e69da 166
618b7f29
TS
167sreal
168sreal::operator- (const sreal &other) const
ac5e69da
JZ
169{
170 int dexp;
618b7f29
TS
171 sreal tmp, r;
172 const sreal *bb;
d1704358 173 const sreal *a_p = this, *b_p = &other;
ac5e69da 174
d1704358
ML
175 int64_t sign = 1;
176 if (a_p->m_exp < b_p->m_exp)
177 {
178 sign = -1;
179 std::swap (a_p, b_p);
180 }
ac5e69da 181
d1704358 182 dexp = a_p->m_exp - b_p->m_exp;
fd27ffab 183 r.m_exp = a_p->m_exp;
ac5e69da
JZ
184 if (dexp > SREAL_BITS)
185 {
d1704358 186 r.m_sig = sign * a_p->m_sig;
ac5e69da
JZ
187 return r;
188 }
189 if (dexp == 0)
fd27ffab 190 bb = b_p;
ac5e69da
JZ
191 else
192 {
fd27ffab 193 tmp = *b_p;
618b7f29 194 tmp.shift_right (dexp);
ac5e69da
JZ
195 bb = &tmp;
196 }
197
d1704358 198 r.m_sig = sign * (a_p->m_sig - bb->m_sig);
618b7f29 199 r.normalize ();
ac5e69da
JZ
200 return r;
201}
202
618b7f29 203/* Return *this * other. */
ac5e69da 204
618b7f29
TS
205sreal
206sreal::operator* (const sreal &other) const
ac5e69da 207{
fd27ffab 208 sreal r;
5007f798 209 if (absu_hwi (m_sig) < SREAL_MIN_SIG || absu_hwi (other.m_sig) < SREAL_MIN_SIG)
ac5e69da 210 {
618b7f29
TS
211 r.m_sig = 0;
212 r.m_exp = -SREAL_MAX_EXP;
ac5e69da
JZ
213 }
214 else
215 {
618b7f29
TS
216 r.m_sig = m_sig * other.m_sig;
217 r.m_exp = m_exp + other.m_exp;
218 r.normalize ();
ac5e69da 219 }
fd27ffab 220
ac5e69da
JZ
221 return r;
222}
223
618b7f29 224/* Return *this / other. */
ac5e69da 225
618b7f29
TS
226sreal
227sreal::operator/ (const sreal &other) const
ac5e69da 228{
fd27ffab
ML
229 gcc_checking_assert (other.m_sig != 0);
230 sreal r;
618b7f29
TS
231 r.m_sig = (m_sig << SREAL_PART_BITS) / other.m_sig;
232 r.m_exp = m_exp - other.m_exp - SREAL_PART_BITS;
233 r.normalize ();
ac5e69da
JZ
234 return r;
235}
This page took 5.042213 seconds and 5 git commands to generate.