Changeset 516e780 in mainline for uspace/lib/math/generic/trunc.c


Ignore:
Timestamp:
2018-08-31T11:55:41Z (7 years ago)
Author:
GitHub <noreply@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
fa86fff
Parents:
7f7d642
git-author:
Jiří Zárevúcky <zarevucky.jiri@…> (2018-08-31 11:55:41)
git-committer:
GitHub <noreply@…> (2018-08-31 11:55:41)
Message:

Strip down libmath. (#45)

libmath is mostly unused (except for trunc(), sin() and cos()), and most functions in it are either very imprecise or downright broken. Additionally, it is implemented in manner that conflicts with C standard. Instead of trying to fix all the shortcomings while maintaining unused functionality, I'm opting to simply remove most of it and only keep the parts that are currently necessary.

Later readdition of the removed functions is possible, but there needs to be a reliable way to evaluate their quality first.

File:
1 edited

Legend:

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

    r7f7d642 r516e780  
    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        const int exp_bias = FLT_MAX_EXP - 1;
     58        const int mant_bits = FLT_MANT_DIG - 1;
     59        const uint32_t mant_mask = (UINT32_C(1) << mant_bits) - 1;
    5860
    59         v.val = val;
    60         exp = v.data.parts.exp - FLOAT32_BIAS;
     61        union {
     62                float f;
     63                uint32_t i;
     64        } u = { .f = fabsf(val) };
    6165
    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                 }
     66        int exp = (u.i >> mant_bits) - exp_bias;
    7167
    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         }
     68        /* If value is less than one, return zero with appropriate sign. */
     69        if (exp < 0)
     70                return copysignf(0.0f, val);
    7771
    78         return v.val;
     72        if (exp >= mant_bits)
     73                return val;
     74
     75        /* Truncate irrelevant fraction bits */
     76        u.i &= ~(mant_mask >> exp);
     77        return copysignf(u.f, val);
    7978}
    8079
     
    9493 *
    9594 */
    96 float64_t float64_trunc(float64_t val)
     95double trunc(double val)
    9796{
    98         float64_u v;
    99         int32_t exp;
     97        const int exp_bias = DBL_MAX_EXP - 1;
     98        const int mant_bits = DBL_MANT_DIG - 1;
     99        const uint64_t mant_mask = (UINT64_C(1) << mant_bits) - 1;
    100100
    101         v.val = val;
    102         exp = v.data.parts.exp - FLOAT64_BIAS;
     101        union {
     102                double f;
     103                uint64_t i;
     104        } u = { .f = fabs(val) };
    103105
    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                 }
     106        int exp = ((int)(u.i >> mant_bits)) - exp_bias;
    113107
    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         }
     108        /* If value is less than one, return zero with appropriate sign. */
     109        if (exp < 0)
     110                return copysign(0.0, val);
    119111
    120         return v.val;
     112        if (exp >= mant_bits)
     113                return val;
     114
     115        /* Truncate irrelevant fraction bits */
     116        u.i &= ~(mant_mask >> exp);
     117        return copysign(u.f, val);
    121118}
    122119
Note: See TracChangeset for help on using the changeset viewer.