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 --- |