Changeset 84929b0 in mainline for uspace/lib/math/generic/trunc.c


Ignore:
Timestamp:
2018-08-29T20:06:00Z (6 years ago)
Author:
Jiří Zárevúcky <jiri.zarevucky@…>
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)
Message:

Strip libmath to the bare necessities

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/math/generic/trunc.c

    r184ff675 r84929b0  
    3434 */
    3535
    36 #include <mathtypes.h>
    37 #include <trunc.h>
     36#include <math.h>
     37#include <float.h>
     38#include <stdint.h>
    3839
    3940/** Truncate fractional part (round towards zero)
     
    5253 *
    5354 */
    54 float32_t float32_trunc(float32_t val)
     55float truncf(float val)
    5556{
    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("");
    5860
    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;
    6164
    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) };
    7169
    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;
    7771
    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);
    7982}
    8083
     
    9497 *
    9598 */
    96 float64_t float64_trunc(float64_t val)
     99double trunc(double val)
    97100{
    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("");
    100104
    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;
    103108
    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) };
    113113
    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;
    119115
    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);
    121126}
    122127
Note: See TracChangeset for help on using the changeset viewer.