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> |
32#include "fpbits.h" 33 34#include <assert.h> 35#include <stdint.h> 36 37#include <stdio.h> 38 |
39 |
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); |
43const fp80_t fp80_qnani = BUILD_FP80(1, FP80_FRAC_QNANI, 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); |
46 |
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{ |
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)) { |
175 return fp80_sgn(fp80) > 0 ? fp64_snan : fp64_nsnan; |
176 } else if (fp80_isqnani(fp80)) { |
177 return fp64_qnani; |
178 } else { 179 assert(fp80_isqnan(fp80)); |
180 return fp80_sgn(fp80) > 0 ? fp64_qnan : fp64_nqnan; |
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{ |
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 --- |