Changeset 516e780 in mainline for uspace/lib


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.

Location:
uspace/lib
Files:
3 added
64 deleted
9 edited
8 moved

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/include/fenv.h

    r7f7d642 r516e780  
    11/*
    2  * Copyright (c) 2015 Jiri Svoboda
     2 * Copyright (c) 2018 CZ.NIC, z.s.p.o.
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup libmath
    30  * @{
    31  */
    32 /** @file
    33  */
     29#ifndef _FENV_H
     30#define _FENV_H
    3431
    35 #ifndef LIBMATH_EXP_H_
    36 #define LIBMATH_EXP_H_
     32// TODO
    3733
    38 #include <mathtypes.h>
     34#define FE_TOWARDZERO  0
     35#define FE_TONEAREST   1
     36#define FE_UPWARD      2
     37#define FE_DOWNWARD    3
    3938
    40 extern float32_t float32_exp(float32_t);
    41 extern float64_t float64_exp(float64_t);
     39#define fegetround() FE_TONEAREST
    4240
    4341#endif
    4442
    45 /** @}
    46  */
  • uspace/lib/c/include/float.h

    r7f7d642 r516e780  
    11/*
    2  * Copyright (c) 2015 Jiri Svoboda
     2 * Copyright (c) 2018 CZ.NIC, z.s.p.o.
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup libmath
    30  * @{
    31  */
    32 /** @file
    33  */
     29#ifndef _FLOAT_H
     30#define _FLOAT_H
    3431
    35 #ifndef LIBMATH_ATAN_H_
    36 #define LIBMATH_ATAN_H_
     32// FIXME: <float.h> is freestanding. Just include the compiler-provided file.
    3733
    38 #include <mathtypes.h>
     34#define FLT_MIN __FLT_MIN__
     35#define FLT_DENORM_MIN __FLT_DENORM_MIN__
     36#define FLT_EPSILON __FLT_EPSILON__
    3937
    40 extern float32_t float32_atan(float32_t);
    41 extern float64_t float64_atan(float64_t);
     38#define FLT_MANT_DIG  __FLT_MANT_DIG__
     39#define DBL_MANT_DIG  __DBL_MANT_DIG__
     40#define FLT_MAX_EXP __FLT_MAX_EXP__
     41#define DBL_MAX_EXP __DBL_MAX_EXP__
    4242
    4343#endif
    4444
    45 /** @}
    46  */
  • uspace/lib/math/Makefile

    r7f7d642 r516e780  
    3030ROOT_PATH = $(USPACE_PREFIX)/..
    3131
    32 CONFIG_MAKEFILE = $(ROOT_PATH)/Makefile.config
    33 
    3432LIBRARY = libmath
    3533SOVERSION = 0.0
    3634
    37 EXTRA_CFLAGS += -Iarch/$(UARCH)/include
    38 
    39 -include $(CONFIG_MAKEFILE)
    40 -include arch/$(UARCH)/Makefile.inc
    41 
    42 GENERIC_SOURCES = \
    43         generic/acos.c \
    44         generic/asin.c \
    45         generic/atan.c \
    46         generic/atan2.c \
    47         generic/ceil.c \
    48         generic/cosh.c \
    49         generic/exp.c \
     35SOURCES = \
     36        generic/__fcompare.c \
     37        generic/__fpclassify.c \
     38        generic/__signbit.c \
    5039        generic/fabs.c \
    51         generic/floor.c \
    5240        generic/fmod.c \
    53         generic/frexp.c \
    54         generic/ldexp.c \
    55         generic/log.c \
    56         generic/log10.c \
    57         generic/log2.c \
    58         generic/modf.c \
    59         generic/pow.c \
    60         generic/sinh.c \
    61         generic/sqrt.c \
    62         generic/tan.c \
    63         generic/tanh.c \
     41        generic/nearbyint.c \
     42        generic/round.c \
    6443        generic/trig.c \
    6544        generic/trunc.c
    6645
    67 SOURCES = \
    68         $(GENERIC_SOURCES) \
    69         $(ARCH_SOURCES)
     46TEST_SOURCES = \
     47        test/rounding.c \
     48        test/main.c
    7049
    7150include $(USPACE_PREFIX)/Makefile.common
  • uspace/lib/math/generic/__fcompare.c

    r7f7d642 r516e780  
    11/*
    2  * Copyright (c) 2015 Jiri Svoboda
     2 * Copyright (c) 2018 CZ.NIC, z.s.p.o.
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup libmath
    30  * @{
     29#include <math.h>
     30#include <stdarg.h>
     31
     32/**
     33 * Fallback symbol used when code including <math.h> is compiled with something
     34 * other than GCC or Clang. The function itself must be built with GCC or Clang.
    3135 */
    32 /** @file
    33  */
     36int __fcompare(size_t sz1, size_t sz2, ...)
     37{
     38        va_list ap;
     39        va_start(ap, sz2);
    3440
    35 #include <ceil.h>
    36 #include <math.h>
    37 #include <mathtypes.h>
     41        long double val1;
     42        long double val2;
    3843
    39 /** Ceiling (round towards positive infinity, 32-bit floating point)
    40  *
    41  * @param val Floating point number.
    42  *
    43  * @return Number rounded towards positive infinity.
    44  */
    45 float32_t float32_ceil(float32_t val)
    46 {
    47         float32_u t;
    48         float32_u v;
    49         float32_u r;
    50 
    51         v.val = val;
    52         t.val = trunc_f32(val);
    53 
    54         if (v.data.parts.sign == 1 || val == t.val) {
    55                 r = t;
    56         } else {
    57                 r.val = t.val + 1.0;
     44        switch (sz1) {
     45        case 4:
     46                val1 = (long double) va_arg(ap, double);
     47                break;
     48        case 8:
     49                val1 = (long double) va_arg(ap, double);
     50                break;
     51        default:
     52                val1 = va_arg(ap, long double);
     53                break;
    5854        }
    5955
    60         return r.val;
     56        switch (sz2) {
     57        case 4:
     58                val2 = (long double) va_arg(ap, double);
     59                break;
     60        case 8:
     61                val2 = (long double) va_arg(ap, double);
     62                break;
     63        default:
     64                val2 = va_arg(ap, long double);
     65                break;
     66        }
     67
     68        va_end(ap);
     69
     70        if (isgreaterequal(val1, val2)) {
     71                if (isgreater(val1, val2))
     72                        return __FCOMPARE_GREATER;
     73                else
     74                        return __FCOMPARE_EQUAL;
     75        } else {
     76                if (isless(val1, val2))
     77                        return __FCOMPARE_LESS;
     78                else
     79                        return 0;
     80        }
    6181}
    6282
    63 /** Ceiling (round towards positive infinity, 64-bit floating point)
    64  *
    65  * @param val Floating point number.
    66  *
    67  * @return Number rounded towards positive infinity.
    68  */
    69 float64_t float64_ceil(float64_t val)
    70 {
    71         float64_u t;
    72         float64_u v;
    73         float64_u r;
    74 
    75         v.val = val;
    76         t.val = trunc_f64(val);
    77 
    78         if (v.data.parts.sign == 1 || val == t.val) {
    79                 r = t;
    80         } else {
    81                 r.val = t.val + 1.0;
    82         }
    83 
    84         return r.val;
    85 }
    86 
    87 /** @}
    88  */
  • uspace/lib/math/generic/__fpclassify.c

    r7f7d642 r516e780  
    11/*
    2  * Copyright (c) 2015 Jiri Svoboda
     2 * Copyright (c) 2018 CZ.NIC, z.s.p.o.
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup libmath
    30  * @{
     29#include <math.h>
     30#include <stdarg.h>
     31
     32/**
     33 * Fallback symbol used when code including <math.h> is compiled with something
     34 * other than GCC or Clang. The function itself must be built with GCC or Clang.
    3135 */
    32 /** @file
    33  */
     36int __fpclassify(size_t sz, ...)
     37{
     38        va_list ap;
     39        va_start(ap, sz);
    3440
    35 #include <math.h>
    36 #include <sqrt.h>
     41        int result;
    3742
    38 /** Single precision square root
    39  *
    40  * Compute square root.
    41  *
    42  * @param val Value
    43  *
    44  * @return Square root.
    45  *
    46  */
    47 float32_t float32_sqrt(float32_t val)
    48 {
    49         return pow_f32(val, 0.5);
     43        switch (sz) {
     44        case 4:
     45                result = fpclassify((float) va_arg(ap, double));
     46                break;
     47        case 8:
     48                result = fpclassify(va_arg(ap, double));
     49                break;
     50        default:
     51                result = fpclassify(va_arg(ap, long double));
     52                break;
     53        }
     54
     55        va_end(ap);
     56        return result;
    5057}
    5158
    52 /** Double precision square root
    53  *
    54  * Compute squre root.
    55  *
    56  * @param val Value
    57  *
    58  * @return Square root.
    59  *
    60  */
    61 float64_t float64_sqrt(float64_t val)
    62 {
    63         return pow_f64(val, 0.5);
    64 }
    65 
    66 /** @}
    67  */
  • uspace/lib/math/generic/__signbit.c

    r7f7d642 r516e780  
    11/*
    2  * Copyright (c) 2015 Jiri Svoboda
     2 * Copyright (c) 2018 CZ.NIC, z.s.p.o.
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup libmath
    30  * @{
     29#include <math.h>
     30#include <stdarg.h>
     31
     32/**
     33 * Fallback symbol used when code including <math.h> is compiled with something
     34 * other than GCC or Clang. The function itself must be built with GCC or Clang.
    3135 */
    32 /** @file
    33  */
     36int __signbit(size_t sz, ...)
     37{
     38        va_list ap;
     39        va_start(ap, sz);
    3440
    35 #include <math.h>
    36 #include <tan.h>
     41        int result;
    3742
    38 /** Tangent (32-bit floating point)
    39  *
    40  * Compute tangent value.
    41  *
    42  * @param arg Tangent argument.
    43  *
    44  * @return Tangent value.
    45  *
    46  */
    47 float32_t float32_tan(float32_t arg)
    48 {
    49         return sin_f32(arg) / cos_f32(arg);
     43        switch (sz) {
     44        case 4:
     45                result = signbit(va_arg(ap, double));
     46                break;
     47        case 8:
     48                result = signbit(va_arg(ap, double));
     49                break;
     50        default:
     51                result = signbit(va_arg(ap, long double));
     52                break;
     53        }
     54
     55        va_end(ap);
     56        return result;
    5057}
    5158
    52 /** Sine (64-bit floating point)
    53  *
    54  * Compute sine value.
    55  *
    56  * @param arg Sine argument.
    57  *
    58  * @return Sine value.
    59  *
    60  */
    61 float64_t float64_tan(float64_t arg)
    62 {
    63         return sin_f64(arg) / cos_f64(arg);
    64 }
    65 
    66 
    67 /** @}
    68  */
  • uspace/lib/math/generic/fabs.c

    r7f7d642 r516e780  
    11/*
    2  * Copyright (c) 2015 Jiri Svoboda
     2 * Copyright (c) 2014 Martin Decky
    33 * All rights reserved.
    44 *
     
    3434
    3535#include <math.h>
    36 #include <fabs.h>
    3736
    38 /** Absolute value (32-bit floating point)
    39  *
    40  * Compute absolute value.
    41  *
    42  * @param arg Argument.
    43  *
    44  * @return Absolute value.
    45  *
    46  */
    47 float32_t float32_fabs(float32_t arg)
     37float fabsf(float val)
    4838{
    49         if (arg < 0.0)
    50                 return -arg;
    51         else
    52                 return arg;
     39        return copysignf(val, 1.0f);
    5340}
    5441
    55 /** Absolute value (64-bit floating point)
    56  *
    57  * Compute absolute value.
    58  *
    59  * @param arg Argument.
    60  *
    61  * @return Absolute value.
    62  *
    63  */
    64 float64_t float64_fabs(float64_t arg)
     42double fabs(double val)
    6543{
    66         if (arg < 0.0)
    67                 return -arg;
    68         else
    69                 return arg;
     44        return copysign(val, 1.0);
    7045}
    7146
  • uspace/lib/math/generic/fmod.c

    r7f7d642 r516e780  
    3333 */
    3434
    35 #include <fmod.h>
    3635#include <math.h>
    3736
     
    5251 *
    5352 */
    54 float32_t float32_fmod(float32_t dividend, float32_t divisor)
     53float fmodf(float dividend, float divisor)
    5554{
    5655        // FIXME: replace with exact arithmetics
    5756
    58         float32_t quotient = trunc_f32(dividend / divisor);
     57        float quotient = truncf(dividend / divisor);
    5958
    6059        return (dividend - quotient * divisor);
     
    7776 *
    7877 */
    79 float64_t float64_fmod(float64_t dividend, float64_t divisor)
     78double fmod(double dividend, double divisor)
    8079{
    8180        // FIXME: replace with exact arithmetics
    8281
    83         float64_t quotient = trunc_f64(dividend / divisor);
     82        double quotient = trunc(dividend / divisor);
    8483
    8584        return (dividend - quotient * divisor);
  • uspace/lib/math/generic/round.c

    r7f7d642 r516e780  
    3535
    3636#include <math.h>
    37 #include <pow.h>
     37#include <float.h>
     38#include <stdint.h>
    3839
    39 /** Single precision power
    40  *
    41  * Compute power value.
    42  *
    43  * @param x Base
    44  * @param y Exponent
    45  *
    46  * @return Cosine value.
    47  *
     40/**
     41 * Rounds its argument to the nearest integer value in floating-point format,
     42 * rounding halfway cases away from zero, regardless of the current rounding
     43 * direction.
    4844 */
    49 float32_t float32_pow(float32_t x, float32_t y)
     45float roundf(float val)
    5046{
    51         /* x^y = (e ^ log(x))^y = e ^ (log(x) * y) */
    52         return exp_f32(log_f32(x) * y);
     47        const int exp_bias = FLT_MAX_EXP - 1;
     48        const int mant_bits = FLT_MANT_DIG - 1;
     49
     50        union {
     51                float f;
     52                uint32_t i;
     53        } u = { .f = fabsf(val) };
     54
     55        int exp = (u.i >> mant_bits) - exp_bias;
     56
     57        /* If value is less than 0.5, return zero with appropriate sign. */
     58        if (exp < -1)
     59                return copysignf(0.0f, val);
     60
     61        /* If exponent is exactly mant_bits, adding 0.5 could change the result. */
     62        if (exp >= mant_bits)
     63                return val;
     64
     65        /* Use trunc with adjusted value to do the rounding. */
     66        return copysignf(truncf(u.f + 0.5), val);
    5367}
    5468
    55 /** Double precision power
    56  *
    57  * Compute power value.
    58  *
    59  * @param x Base
    60  * @param y Exponent
    61  *
    62  * @return Cosine value.
    63  *
     69/**
     70 * Rounds its argument to the nearest integer value in floating-point format,
     71 * rounding halfway cases away from zero, regardless of the current rounding
     72 * direction.
    6473 */
    65 float64_t float64_pow(float64_t x, float64_t y)
     74double round(double val)
    6675{
    67         /* x^y = (e ^ log(x))^y = e ^ (log(x) * y) */
    68         return exp_f64(log_f64(x) * y);
     76        const int exp_bias = DBL_MAX_EXP - 1;
     77        const int mant_bits = DBL_MANT_DIG - 1;
     78
     79        union {
     80                double f;
     81                uint64_t i;
     82        } u = { .f = fabs(val) };
     83
     84        int exp = ((int)(u.i >> mant_bits)) - exp_bias;
     85
     86        /* If value is less than 0.5, return zero with appropriate sign. */
     87        if (exp < -1)
     88                return copysign(0.0, val);
     89
     90        /* If exponent is exactly mant_bits, adding 0.5 could change the result. */
     91        if (exp >= mant_bits)
     92                return val;
     93
     94        /* Use trunc with adjusted value to do the rounding. */
     95        return copysign(trunc(u.f + 0.5), val);
    6996}
    7097
  • uspace/lib/math/generic/trig.c

    r7f7d642 r516e780  
    3535
    3636#include <math.h>
    37 #include <trig.h>
    3837
    3938#define TAYLOR_DEGREE_32 13
     
    4140
    4241/** Precomputed values for factorial (starting from 1!) */
    43 static float64_t factorials[TAYLOR_DEGREE_64] = {
     42static double factorials[TAYLOR_DEGREE_64] = {
    4443        1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800,
    4544        479001600, 6227020800.0L, 87178291200.0L, 1307674368000.0L,
     
    6059 *
    6160 */
    62 static float32_t taylor_sin_32(float32_t arg)
    63 {
    64         float32_t ret = 0;
    65         float32_t nom = 1;
     61static float taylor_sin_32(float arg)
     62{
     63        float ret = 0;
     64        float nom = 1;
    6665
    6766        for (unsigned int i = 0; i < TAYLOR_DEGREE_32; i++) {
     
    8988 *
    9089 */
    91 static float64_t taylor_sin_64(float64_t arg)
    92 {
    93         float64_t ret = 0;
    94         float64_t nom = 1;
     90static double taylor_sin_64(double arg)
     91{
     92        double ret = 0;
     93        double nom = 1;
    9594
    9695        for (unsigned int i = 0; i < TAYLOR_DEGREE_64; i++) {
     
    118117 *
    119118 */
    120 static float32_t taylor_cos_32(float32_t arg)
    121 {
    122         float32_t ret = 1;
    123         float32_t nom = 1;
     119static float taylor_cos_32(float arg)
     120{
     121        float ret = 1;
     122        float nom = 1;
    124123
    125124        for (unsigned int i = 0; i < TAYLOR_DEGREE_32; i++) {
     
    147146 *
    148147 */
    149 static float64_t taylor_cos_64(float64_t arg)
    150 {
    151         float64_t ret = 1;
    152         float64_t nom = 1;
     148static double taylor_cos_64(double arg)
     149{
     150        double ret = 1;
     151        double nom = 1;
    153152
    154153        for (unsigned int i = 0; i < TAYLOR_DEGREE_64; i++) {
     
    176175 *
    177176 */
    178 static float32_t base_sin_32(float32_t arg)
     177static float base_sin_32(float arg)
    179178{
    180179        unsigned int period = arg / (M_PI / 4);
     
    209208 *
    210209 */
    211 static float64_t base_sin_64(float64_t arg)
     210static double base_sin_64(double arg)
    212211{
    213212        unsigned int period = arg / (M_PI / 4);
     
    242241 *
    243242 */
    244 static float32_t base_cos_32(float32_t arg)
     243static float base_cos_32(float arg)
    245244{
    246245        unsigned int period = arg / (M_PI / 4);
     
    275274 *
    276275 */
    277 static float64_t base_cos_64(float64_t arg)
     276static double base_cos_64(double arg)
    278277{
    279278        unsigned int period = arg / (M_PI / 4);
     
    305304 *
    306305 */
    307 float32_t float32_sin(float32_t arg)
    308 {
    309         float32_t base_arg = fmod_f32(arg, 2 * M_PI);
     306float sinf(float arg)
     307{
     308        float base_arg = fmodf(arg, 2 * M_PI);
    310309
    311310        if (base_arg < 0)
     
    324323 *
    325324 */
    326 float64_t float64_sin(float64_t arg)
    327 {
    328         float64_t base_arg = fmod_f64(arg, 2 * M_PI);
     325double sin(double arg)
     326{
     327        double base_arg = fmod(arg, 2 * M_PI);
    329328
    330329        if (base_arg < 0)
     
    343342 *
    344343 */
    345 float32_t float32_cos(float32_t arg)
    346 {
    347         float32_t base_arg = fmod_f32(arg, 2 * M_PI);
     344float cosf(float arg)
     345{
     346        float base_arg = fmodf(arg, 2 * M_PI);
    348347
    349348        if (base_arg < 0)
     
    362361 *
    363362 */
    364 float64_t float64_cos(float64_t arg)
    365 {
    366         float64_t base_arg = fmod_f64(arg, 2 * M_PI);
     363double cos(double arg)
     364{
     365        double base_arg = fmod(arg, 2 * M_PI);
    367366
    368367        if (base_arg < 0)
  • 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
  • uspace/lib/math/test/main.c

    r7f7d642 r516e780  
    11/*
    2  * Copyright (c) 2015 Jiri Svoboda
     2 * Copyright (c) 2014 Vojtech Horky
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup libmath
    30  * @{
    31  */
    32 /** @file
    33  */
     29#include <stdio.h>
     30#include <pcut/pcut.h>
    3431
    35 #ifndef LIBMATH_LOG_H_
    36 #define LIBMATH_LOG_H_
     32PCUT_INIT;
    3733
    38 #include <mathtypes.h>
     34PCUT_IMPORT(rounding);
    3935
    40 extern float32_t float32_log(float32_t);
    41 extern float64_t float64_log(float64_t);
     36PCUT_MAIN();
    4237
    43 #endif
    44 
    45 /** @}
    46  */
  • uspace/lib/posix/include/posix/math.h

    r7f7d642 r516e780  
    11/*
    2  * Copyright (c) 2011 Petr Koupy
     2 * Copyright (c) 2018 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3030 * @{
    3131 */
    32 /** @file Mathematical operations.
    33  *
    34  * The purpose of this file is only to provide prototypes of mathematical
    35  * functions defined by C standard and by POSIX.
    36  *
    37  * It is up to the application to correctly link with either libmath
    38  * (provided by HelenOS) or by some other math library (such as fdlibm).
    39  */
    4032
    4133#ifndef POSIX_MATH_H_
    4234#define POSIX_MATH_H_
    4335
    44 #ifdef __GNUC__
    45 #define HUGE_VAL (__builtin_huge_val())
     36/*
     37 * Just a pass-through to libc math.h
     38 */
     39#include "libc/math.h"
     40
    4641#endif
    47 
    48 extern double ldexp(double, int);
    49 extern double frexp(double, int *);
    50 
    51 extern double fabs(double);
    52 extern double floor(double);
    53 extern double ceil(double);
    54 extern double modf(double, double *);
    55 extern double fmod(double, double);
    56 extern double pow(double, double);
    57 extern double exp(double);
    58 extern double frexp(double, int *);
    59 extern double expm1(double);
    60 extern double sqrt(double);
    61 extern double log(double);
    62 extern double log10(double);
    63 extern double sin(double);
    64 extern double sinh(double);
    65 extern double asin(double);
    66 extern double asinh(double);
    67 extern double cos(double);
    68 extern double cosh(double);
    69 extern double acos(double);
    70 extern double acosh(double);
    71 extern double tan(double);
    72 extern double tanh(double);
    73 extern double atan(double);
    74 extern double atanh(double);
    75 extern double atan2(double, double);
    76 extern double copysign(double, double);
    77 
    78 #endif /* POSIX_MATH_H_ */
    7942
    8043/** @}
  • uspace/lib/softfloat/Makefile

    r7f7d642 r516e780  
    3030USPACE_PREFIX = ../..
    3131LIBRARY = libsoftfloat
    32 EXTRA_CFLAGS += $(LIBMATH_INCLUDES_FLAGS)
    3332
    3433SOURCES = \
  • uspace/lib/softfloat/comparison.c

    r7f7d642 r516e780  
    681681}
    682682
     683int __aeabi_fcmpun(float32_t a, float32_t b)
     684{
     685        float32_u ua;
     686        ua.val = a;
     687
     688        float32_u ub;
     689        ub.val = b;
     690
     691        // TODO: sigNaNs
     692        return is_float32_nan(ua.data) || is_float32_nan(ub.data);
     693}
     694
    683695#endif
    684696
     
    920932}
    921933
     934int __aeabi_dcmpun(float64_t a, float64_t b)
     935{
     936        float64_u ua;
     937        ua.val = a;
     938
     939        float64_u ub;
     940        ub.val = b;
     941
     942        // TODO: sigNaNs
     943        return is_float64_nan(ua.data) || is_float64_nan(ub.data);
     944}
     945
    922946#endif
    923947
  • uspace/lib/softfloat/comparison.h

    r7f7d642 r516e780  
    9393extern int __aeabi_fcmple(float32_t, float32_t);
    9494extern int __aeabi_fcmpeq(float32_t, float32_t);
     95extern int __aeabi_fcmpun(float32_t, float32_t);
    9596#endif
    9697
     
    109110extern int __aeabi_dcmpge(float64_t, float64_t);
    110111extern int __aeabi_dcmple(float64_t, float64_t);
     112extern int __aeabi_dcmpun(float64_t, float64_t);
    111113#endif
    112114
Note: See TracChangeset for help on using the changeset viewer.