Branch data Line data Source code
1 : : // Copyright 2019-2026 David Robillard <d@drobilla.net> 2 : : // SPDX-License-Identifier: ISC 3 : : 4 : : #include "double_to_decimal.h" 5 : : #include "attributes.h" 6 : : #include "digits.h" 7 : : #include "warnings.h" 8 : : 9 : : #include <assert.h> 10 : : #include <math.h> 11 : : #include <stdbool.h> 12 : : #include <stdint.h> 13 : : 14 : : static BigDecimalKind 15 : 31783 : number_kind(const double d) 16 : : { 17 : : EXESS_DISABLE_CONVERSION_WARNINGS 18 [ + + + + : 31783 : const int fpclass = fpclassify(d); + + + + ] 19 : 31783 : const bool is_negative = signbit(d); 20 : : EXESS_RESTORE_WARNINGS 21 : : 22 [ + + + + ]: 31783 : switch (fpclass) { 23 : 74 : case FP_ZERO: 24 [ + + ]: 74 : return is_negative ? EXESS_NEGATIVE_ZERO : EXESS_POSITIVE_ZERO; 25 : 1009 : case FP_INFINITE: 26 [ + + ]: 1009 : return is_negative ? EXESS_NEGATIVE_INFINITY : EXESS_POSITIVE_INFINITY; 27 : 30667 : case FP_NORMAL: 28 : : case FP_SUBNORMAL: 29 [ + + ]: 30667 : return is_negative ? EXESS_NEGATIVE : EXESS_POSITIVE; 30 : 33 : default: 31 : 33 : break; 32 : : } 33 : : 34 : 33 : return EXESS_NAN; 35 : : } 36 : : 37 : : EXESS_I_NONBLOCKING BigDecimal 38 : 31783 : double_to_decimal(const double d, const size_t digits_size, char* const digits) 39 : : { 40 : 31783 : BigDecimal value = {number_kind(d), 0U, 0}; 41 [ + + + + ]: 31783 : if (value.kind != EXESS_NEGATIVE && value.kind != EXESS_POSITIVE) { 42 : 1116 : return value; 43 : : } 44 : : 45 : 30667 : const ExessDigitCount count = generate_digits(fabs(d), digits_size, digits); 46 : : 47 [ + + - + ]: 30667 : assert(count.count == 1 || digits[count.count - 1] != '0'); 48 : : 49 : 30667 : value.n_digits = (uint8_t)count.count; 50 : 30667 : value.expt = (int16_t)(count.expt + 1); 51 : 30667 : return value; 52 : : }