fp80.c (9899:0392ef94d766) fp80.c (10480:5d4ebc92d32e)
1/*
2 * Copyright (c) 2013, Andreas Sandberg
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *

--- 14 unchanged lines hidden (view full) ---

23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
27 * OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include <fputils/fp80.h>
1/*
2 * Copyright (c) 2013, Andreas Sandberg
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *

--- 14 unchanged lines hidden (view full) ---

23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
27 * OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include <fputils/fp80.h>
31#include <fputils/fp64.h>
31#include "fpbits.h"
32
33#include <assert.h>
34#include <stdint.h>
35
36#include <stdio.h>
37
32#include "fpbits.h"
33
34#include <assert.h>
35#include <stdint.h>
36
37#include <stdio.h>
38
38typedef union {
39 uint64_t bits;
40 double value;
41} fp64_t;
42
39
43
44const fp80_t fp80_pinf = BUILD_FP80(0, 0, FP80_EXP_SPECIAL);
45const fp80_t fp80_ninf = BUILD_FP80(1, 0, FP80_EXP_SPECIAL);
46const fp80_t fp80_qnan = BUILD_FP80(0, FP80_FRAC_QNAN, FP80_EXP_SPECIAL);
40const fp80_t fp80_pinf = BUILD_FP80(0, 0, FP80_EXP_SPECIAL);
41const fp80_t fp80_ninf = BUILD_FP80(1, 0, FP80_EXP_SPECIAL);
42const fp80_t fp80_qnan = BUILD_FP80(0, FP80_FRAC_QNAN, FP80_EXP_SPECIAL);
47const fp80_t fp80_qnani = BUILD_FP80(1, FP80_FRAC_QNANI, FP80_EXP_SPECIAL);
43const fp80_t fp80_qnani = BUILD_FP80(1, FP80_FRAC_QNANI, FP80_EXP_SPECIAL);
48const fp80_t fp80_snan = BUILD_FP80(0, FP80_FRAC_SNAN, FP80_EXP_SPECIAL);
49const fp80_t fp80_nan = BUILD_FP80(0, FP80_FRAC_QNAN, FP80_EXP_SPECIAL);
44const fp80_t fp80_snan = BUILD_FP80(0, FP80_FRAC_SNAN, FP80_EXP_SPECIAL);
45const fp80_t fp80_nan = BUILD_FP80(0, FP80_FRAC_QNAN, FP80_EXP_SPECIAL);
50
46
51static const fp64_t fp64_pinf = BUILD_FP64(0, 0, FP64_EXP_SPECIAL);
52static const fp64_t fp64_ninf = BUILD_FP64(1, 0, FP64_EXP_SPECIAL);
53static const fp64_t fp64_qnan = BUILD_FP64(0, FP64_FRAC_QNAN,
54 FP64_EXP_SPECIAL);
55static const fp64_t fp64_nqnan = BUILD_FP64(1, FP64_FRAC_QNAN,
56 FP64_EXP_SPECIAL);
57static const fp64_t fp64_qnani = BUILD_FP64(1, FP64_FRAC_QNANI,
58 FP64_EXP_SPECIAL);
59static const fp64_t fp64_snan = BUILD_FP64(0, FP64_FRAC_SNAN,
60 FP64_EXP_SPECIAL);
61static const fp64_t fp64_nsnan = BUILD_FP64(1, FP64_FRAC_SNAN,
62 FP64_EXP_SPECIAL);
63
64static double
65build_fp64(int sign, uint64_t frac, int exp)
66{
67 const fp64_t f = BUILD_FP64(sign, frac, exp);
68
69 return f.value;
70}
71
72int
73fp80_sgn(fp80_t fp80)
74{
75 return (fp80.repr.se & FP80_SIGN_BIT) ? -1 : 1;
76}
77
78int
79fp80_isspecial(fp80_t fp80)

--- 82 unchanged lines hidden (view full) ---

162 assert(fp80_isfinite(fp80));
163 return FP_NORMAL;
164 }
165}
166
167double
168fp80_cvtd(fp80_t fp80)
169{
47int
48fp80_sgn(fp80_t fp80)
49{
50 return (fp80.repr.se & FP80_SIGN_BIT) ? -1 : 1;
51}
52
53int
54fp80_isspecial(fp80_t fp80)

--- 82 unchanged lines hidden (view full) ---

137 assert(fp80_isfinite(fp80));
138 return FP_NORMAL;
139 }
140}
141
142double
143fp80_cvtd(fp80_t fp80)
144{
145 return fp80_cvtfp64(fp80).value;
146}
147
148fp64_t
149fp80_cvtfp64(fp80_t fp80)
150{
170 const int sign = fp80.repr.se & FP80_SIGN_BIT;
171
172 if (!fp80_isspecial(fp80)) {
173 const uint64_t frac = fp80.repr.fi;
174 const int unb_exp = FP80_EXP(fp80) - FP80_EXP_BIAS;
175 const int fp64_exp = unb_exp + FP64_EXP_BIAS;
176 const uint64_t fp64_frac = frac >> (FP80_FRAC_BITS - FP64_FRAC_BITS);
177

--- 8 unchanged lines hidden (view full) ---

186 } else {
187 /* Infinity */
188 return build_fp64(sign, 0, FP64_EXP_SPECIAL);
189 }
190 } else {
191 if (fp80_isinf(fp80)) {
192 return build_fp64(sign, 0, FP64_EXP_SPECIAL);
193 } else if (fp80_issnan(fp80)) {
151 const int sign = fp80.repr.se & FP80_SIGN_BIT;
152
153 if (!fp80_isspecial(fp80)) {
154 const uint64_t frac = fp80.repr.fi;
155 const int unb_exp = FP80_EXP(fp80) - FP80_EXP_BIAS;
156 const int fp64_exp = unb_exp + FP64_EXP_BIAS;
157 const uint64_t fp64_frac = frac >> (FP80_FRAC_BITS - FP64_FRAC_BITS);
158

--- 8 unchanged lines hidden (view full) ---

167 } else {
168 /* Infinity */
169 return build_fp64(sign, 0, FP64_EXP_SPECIAL);
170 }
171 } else {
172 if (fp80_isinf(fp80)) {
173 return build_fp64(sign, 0, FP64_EXP_SPECIAL);
174 } else if (fp80_issnan(fp80)) {
194 return fp80_sgn(fp80) > 0 ? fp64_snan.value : fp64_nsnan.value;
175 return fp80_sgn(fp80) > 0 ? fp64_snan : fp64_nsnan;
195 } else if (fp80_isqnani(fp80)) {
176 } else if (fp80_isqnani(fp80)) {
196 return fp64_qnani.value;
177 return fp64_qnani;
197 } else {
198 assert(fp80_isqnan(fp80));
178 } else {
179 assert(fp80_isqnan(fp80));
199 return fp80_sgn(fp80) > 0 ? fp64_qnan.value : fp64_nqnan.value;
180 return fp80_sgn(fp80) > 0 ? fp64_qnan : fp64_nqnan;
200 }
201 }
202}
203
204fp80_t
205fp80_cvfd(double value)
206{
207 const fp64_t fp64 = { .value = value };
181 }
182 }
183}
184
185fp80_t
186fp80_cvfd(double value)
187{
188 const fp64_t fp64 = { .value = value };
189
190 return fp80_cvffp64(fp64);
191}
192
193fp80_t
194fp80_cvffp64(fp64_t fp64)
195{
208 const uint64_t frac = FP64_FRAC(fp64);
209 const unsigned exp = FP64_EXP(fp64);
210 const int unb_exp = exp - FP64_EXP_BIAS;
211 const uint64_t fp80_frac = frac << (FP80_FRAC_BITS - FP64_FRAC_BITS);
212
213 if (exp != 0) {
214 // Normal, inf, nan
215 const unsigned fp80_exp = exp == FP64_EXP_SPECIAL ?

--- 30 unchanged lines hidden ---
196 const uint64_t frac = FP64_FRAC(fp64);
197 const unsigned exp = FP64_EXP(fp64);
198 const int unb_exp = exp - FP64_EXP_BIAS;
199 const uint64_t fp80_frac = frac << (FP80_FRAC_BITS - FP64_FRAC_BITS);
200
201 if (exp != 0) {
202 // Normal, inf, nan
203 const unsigned fp80_exp = exp == FP64_EXP_SPECIAL ?

--- 30 unchanged lines hidden ---