Changeset 84929b0 in mainline for uspace/lib/math/generic/trunc.c
- Timestamp:
- 2018-08-29T20:06:00Z (6 years ago)
- Children:
- ed9043f7
- Parents:
- 184ff675
- git-author:
- Jiří Zárevúcky <jiri.zarevucky@…> (2018-08-29 19:44:33)
- git-committer:
- Jiří Zárevúcky <jiri.zarevucky@…> (2018-08-29 20:06:00)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/math/generic/trunc.c
r184ff675 r84929b0 34 34 */ 35 35 36 #include <mathtypes.h> 37 #include <trunc.h> 36 #include <math.h> 37 #include <float.h> 38 #include <stdint.h> 38 39 39 40 /** Truncate fractional part (round towards zero) … … 52 53 * 53 54 */ 54 float 32_t float32_trunc(float32_t val)55 float truncf(float val) 55 56 { 56 float32_u v; 57 int32_t exp; 57 /* If the input is a nan, return a canonical nan. */ 58 if (isnan(val)) 59 return __builtin_nanf(""); 58 60 59 v.val = val; 60 exp = v.data.parts.exp - FLOAT32_BIAS; 61 const int exp_bias = FLT_MAX_EXP - 1; 62 const int mant_bits = FLT_MANT_DIG - 1; 63 const uint32_t mant_mask = (UINT32_C(1) << mant_bits) - 1; 61 64 62 if (exp < 0) { 63 /* -1 < val < 1 => result is +0 or -0 */ 64 v.data.parts.exp = 0; 65 v.data.parts.fraction = 0; 66 } else if (exp >= FLOAT32_FRACTION_SIZE) { 67 if (exp == 1024) { 68 /* val is +inf, -inf or NaN => trigger an exception */ 69 // FIXME TODO 70 } 65 union { 66 float f; 67 uint32_t i; 68 } u = { .f = fabsf(val) }; 71 69 72 /* All bits in val are relevant for the result */ 73 } else { 74 /* Truncate irrelevant fraction bits */ 75 v.data.parts.fraction &= ~(UINT32_C(0x007fffff) >> exp); 76 } 70 int exp = (u.i >> mant_bits) - exp_bias; 77 71 78 return v.val; 72 /* If value is less than one, return zero with appropriate sign. */ 73 if (exp < 0) 74 return copysignf(0.0f, val); 75 76 if (exp >= mant_bits) 77 return val; 78 79 /* Truncate irrelevant fraction bits */ 80 u.i &= ~(mant_mask >> exp); 81 return copysignf(u.f, val); 79 82 } 80 83 … … 94 97 * 95 98 */ 96 float64_t float64_trunc(float64_tval)99 double trunc(double val) 97 100 { 98 float64_u v; 99 int32_t exp; 101 /* If the input is a nan, return a canonical nan. */ 102 if (isnan(val)) 103 return __builtin_nan(""); 100 104 101 v.val = val; 102 exp = v.data.parts.exp - FLOAT64_BIAS; 105 const int exp_bias = DBL_MAX_EXP - 1; 106 const int mant_bits = DBL_MANT_DIG - 1; 107 const uint64_t mant_mask = (UINT64_C(1) << mant_bits) - 1; 103 108 104 if (exp < 0) { 105 /* -1 < val < 1 => result is +0 or -0 */ 106 v.data.parts.exp = 0; 107 v.data.parts.fraction = 0; 108 } else if (exp >= FLOAT64_FRACTION_SIZE) { 109 if (exp == 1024) { 110 /* val is +inf, -inf or NaN => trigger an exception */ 111 // FIXME TODO 112 } 109 union { 110 double f; 111 uint64_t i; 112 } u = { .f = fabs(val) }; 113 113 114 /* All bits in val are relevant for the result */ 115 } else { 116 /* Truncate irrelevant fraction bits */ 117 v.data.parts.fraction &= ~(UINT64_C(0x000fffffffffffff) >> exp); 118 } 114 int exp = ((int)(u.i >> mant_bits)) - exp_bias; 119 115 120 return v.val; 116 /* If value is less than one, return zero with appropriate sign. */ 117 if (exp < 0) 118 return copysign(0.0, val); 119 120 if (exp >= mant_bits) 121 return val; 122 123 /* Truncate irrelevant fraction bits */ 124 u.i &= ~(mant_mask >> exp); 125 return copysign(u.f, val); 121 126 } 122 127
Note:
See TracChangeset
for help on using the changeset viewer.