LCOV - code coverage report
Current view: top level - src - bigfloat.cpp (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 69 116 59.5 %
Date: 1970-01-01 00:00:01 Functions: 16 26 61.5 %
Branches: 11 16 68.8 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2017 Andrew Kelley
       3                 :            :  *
       4                 :            :  * This file is part of zig, which is MIT licensed.
       5                 :            :  * See http://opensource.org/licenses/MIT
       6                 :            :  */
       7                 :            : 
       8                 :            : #include "bigfloat.hpp"
       9                 :            : #include "bigint.hpp"
      10                 :            : #include "buffer.hpp"
      11                 :            : #include "softfloat.hpp"
      12                 :            : #include "parse_f128.h"
      13                 :            : #include <stdio.h>
      14                 :            : #include <math.h>
      15                 :            : #include <errno.h>
      16                 :            : 
      17                 :            : 
      18                 :          0 : void bigfloat_init_128(BigFloat *dest, float128_t x) {
      19                 :          0 :     dest->value = x;
      20                 :          0 : }
      21                 :            : 
      22                 :          0 : void bigfloat_init_16(BigFloat *dest, float16_t x) {
      23                 :          0 :     f16_to_f128M(x, &dest->value);
      24                 :          0 : }
      25                 :            : 
      26                 :      18535 : void bigfloat_init_32(BigFloat *dest, float x) {
      27                 :            :     float32_t f32_val;
      28                 :      18535 :     memcpy(&f32_val, &x, sizeof(float));
      29                 :      18535 :     f32_to_f128M(f32_val, &dest->value);
      30                 :      18535 : }
      31                 :            : 
      32                 :          0 : void bigfloat_init_64(BigFloat *dest, double x) {
      33                 :            :     float64_t f64_val;
      34                 :          0 :     memcpy(&f64_val, &x, sizeof(double));
      35                 :          0 :     f64_to_f128M(f64_val, &dest->value);
      36                 :          0 : }
      37                 :            : 
      38                 :      86337 : void bigfloat_init_bigfloat(BigFloat *dest, const BigFloat *x) {
      39                 :      86337 :     memcpy(&dest->value, &x->value, sizeof(float128_t));
      40                 :      86337 : }
      41                 :            : 
      42                 :      10000 : void bigfloat_init_bigint(BigFloat *dest, const BigInt *op) {
      43                 :      10000 :     ui32_to_f128M(0, &dest->value);
      44         [ +  + ]:      10000 :     if (op->digit_count == 0)
      45                 :        542 :         return;
      46                 :            : 
      47                 :            :     float128_t base;
      48                 :       9458 :     ui64_to_f128M(UINT64_MAX, &base);
      49                 :       9458 :     const uint64_t *digits = bigint_ptr(op);
      50                 :            : 
      51                 :       9458 :     for (size_t i = op->digit_count - 1;;) {
      52                 :            :         float128_t digit_f128;
      53                 :       9474 :         ui64_to_f128M(digits[i], &digit_f128);
      54                 :            : 
      55                 :       9474 :         f128M_mulAdd(&dest->value, &base, &digit_f128, &dest->value);
      56                 :            : 
      57         [ +  + ]:       9474 :         if (i == 0) {
      58         [ +  + ]:       9458 :             if (op->is_negative) {
      59                 :            :                 float128_t zero_f128;
      60                 :       3910 :                 ui32_to_f128M(0, &zero_f128);
      61                 :       3910 :                 f128M_sub(&zero_f128, &dest->value, &dest->value);
      62                 :            :             }
      63                 :      10000 :             return;
      64                 :            :         }
      65                 :         16 :         i -= 1;
      66                 :         16 :     }
      67                 :            : }
      68                 :            : 
      69                 :      18535 : Error bigfloat_init_buf(BigFloat *dest, const uint8_t *buf_ptr, size_t buf_len) {
      70                 :      18535 :     char *str_begin = (char *)buf_ptr;
      71                 :            :     char *str_end;
      72                 :            : 
      73                 :      18535 :     errno = 0;
      74                 :      18535 :     dest->value = parse_f128(str_begin, &str_end);
      75         [ -  + ]:      18535 :     if (errno) {
      76                 :          0 :         return ErrorOverflow;
      77                 :            :     }
      78                 :            : 
      79                 :      18535 :     assert(str_end <= ((char*)buf_ptr) + buf_len);
      80                 :      18535 :     return ErrorNone;
      81                 :            : }
      82                 :            : 
      83                 :         18 : void bigfloat_add(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {
      84                 :         18 :     f128M_add(&op1->value, &op2->value, &dest->value);
      85                 :         18 : }
      86                 :            : 
      87                 :      11308 : void bigfloat_negate(BigFloat *dest, const BigFloat *op) {
      88                 :            :     float128_t zero_f128;
      89                 :      11308 :     ui32_to_f128M(0, &zero_f128);
      90                 :      11308 :     f128M_sub(&zero_f128, &op->value, &dest->value);
      91                 :      11308 : }
      92                 :            : 
      93                 :          0 : void bigfloat_sub(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {
      94                 :          0 :     f128M_sub(&op1->value, &op2->value, &dest->value);
      95                 :          0 : }
      96                 :            : 
      97                 :         32 : void bigfloat_mul(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {
      98                 :         32 :     f128M_mul(&op1->value, &op2->value, &dest->value);
      99                 :         32 : }
     100                 :            : 
     101                 :         12 : void bigfloat_div(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {
     102                 :         12 :     f128M_div(&op1->value, &op2->value, &dest->value);
     103                 :         12 : }
     104                 :            : 
     105                 :          0 : void bigfloat_div_trunc(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {
     106                 :          0 :     f128M_div(&op1->value, &op2->value, &dest->value);
     107                 :          0 :     f128M_roundToInt(&dest->value, softfloat_round_minMag, false, &dest->value);
     108                 :          0 : }
     109                 :            : 
     110                 :          0 : void bigfloat_div_floor(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {
     111                 :          0 :     f128M_div(&op1->value, &op2->value, &dest->value);
     112                 :          0 :     f128M_roundToInt(&dest->value, softfloat_round_min, false, &dest->value);
     113                 :          0 : }
     114                 :            : 
     115                 :          0 : void bigfloat_rem(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {
     116                 :          0 :     f128M_rem(&op1->value, &op2->value, &dest->value);
     117                 :          0 : }
     118                 :            : 
     119                 :          0 : void bigfloat_mod(BigFloat *dest, const BigFloat *op1, const BigFloat *op2) {
     120                 :          0 :     f128M_rem(&op1->value, &op2->value, &dest->value);
     121                 :          0 :     f128M_add(&dest->value, &op2->value, &dest->value);
     122                 :          0 :     f128M_rem(&dest->value, &op2->value, &dest->value);
     123                 :          0 : }
     124                 :            : 
     125                 :          0 : void bigfloat_append_buf(Buf *buf, const BigFloat *op) {
     126                 :          0 :     const size_t extra_len = 100;
     127                 :          0 :     size_t old_len = buf_len(buf);
     128                 :          0 :     buf_resize(buf, old_len + extra_len);
     129                 :            : 
     130                 :            :     // TODO actually print f128
     131                 :          0 :     float64_t f64_value = f128M_to_f64(&op->value);
     132                 :            :     double double_value;
     133                 :          0 :     memcpy(&double_value, &f64_value, sizeof(double));
     134                 :            : 
     135                 :          0 :     int len = snprintf(buf_ptr(buf) + old_len, extra_len, "%f", double_value);
     136                 :          0 :     assert(len > 0);
     137                 :          0 :     buf_resize(buf, old_len + len);
     138                 :          0 : }
     139                 :            : 
     140                 :         56 : Cmp bigfloat_cmp(const BigFloat *op1, const BigFloat *op2) {
     141         [ -  + ]:         56 :     if (f128M_lt(&op1->value, &op2->value)) {
     142                 :          0 :         return CmpLT;
     143         [ +  - ]:         56 :     } else if (f128M_eq(&op1->value, &op2->value)) {
     144                 :         56 :         return CmpEQ;
     145                 :            :     } else {
     146                 :          0 :         return CmpGT;
     147                 :            :     }
     148                 :            : }
     149                 :            : 
     150                 :        648 : float16_t bigfloat_to_f16(const BigFloat *bigfloat) {
     151                 :        648 :     return f128M_to_f16(&bigfloat->value);
     152                 :            : }
     153                 :            : 
     154                 :       2186 : float bigfloat_to_f32(const BigFloat *bigfloat) {
     155                 :       2186 :     float32_t f32_value = f128M_to_f32(&bigfloat->value);
     156                 :            :     float result;
     157                 :       2186 :     memcpy(&result, &f32_value, sizeof(float));
     158                 :       2186 :     return result;
     159                 :            : }
     160                 :            : 
     161                 :      70410 : double bigfloat_to_f64(const BigFloat *bigfloat) {
     162                 :      70410 :     float64_t f64_value = f128M_to_f64(&bigfloat->value);
     163                 :            :     double result;
     164                 :      70410 :     memcpy(&result, &f64_value, sizeof(double));
     165                 :      70410 :     return result;
     166                 :            : }
     167                 :            : 
     168                 :        550 : float128_t bigfloat_to_f128(const BigFloat *bigfloat) {
     169                 :        550 :     return bigfloat->value;
     170                 :            : }
     171                 :            : 
     172                 :        186 : Cmp bigfloat_cmp_zero(const BigFloat *bigfloat) {
     173                 :            :     float128_t zero_float;
     174                 :        186 :     ui32_to_f128M(0, &zero_float);
     175         [ -  + ]:        186 :     if (f128M_lt(&bigfloat->value, &zero_float)) {
     176                 :          0 :         return CmpLT;
     177         [ -  + ]:        186 :     } else if (f128M_eq(&bigfloat->value, &zero_float)) {
     178                 :          0 :         return CmpEQ;
     179                 :            :     } else {
     180                 :        186 :         return CmpGT;
     181                 :            :     }
     182                 :            : }
     183                 :            : 
     184                 :         24 : bool bigfloat_has_fraction(const BigFloat *bigfloat) {
     185                 :            :     float128_t floored;
     186                 :         24 :     f128M_roundToInt(&bigfloat->value, softfloat_round_minMag, false, &floored);
     187                 :         24 :     return !f128M_eq(&floored, &bigfloat->value);
     188                 :            : }
     189                 :            : 
     190                 :          0 : void bigfloat_sqrt(BigFloat *dest, const BigFloat *op) {
     191                 :          0 :     f128M_sqrt(&op->value, &dest->value);
     192                 :          0 : }
     193                 :            : 
     194                 :        112 : bool bigfloat_is_nan(const BigFloat *op) {
     195                 :        112 :     return f128M_isSignalingNaN(&op->value);
     196                 :            : }

Generated by: LCOV version 1.14