1 /* 2 * Copyright (c) 2019, The Linux Foundation. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * * Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above 10 * copyright notice, this list of conditions and the following 11 * disclaimer in the documentation and/or other materials provided 12 * with the distribution. 13 * * Neither the name of The Linux Foundation nor the names of its 14 * contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #ifndef STD_DTOA_H 31 #define STD_DTOA_H 32 33 // 34 // Constant Definitions 35 // 36 37 // For floating point numbers, the range of a double precision number is 38 // approximately +/- 10 ^ 308.25 as per the IEEE Standard 754. 39 // As such, the maximum size of the integer portion of the 40 // string is assumed to be 311 (309 + sign + \0). The maximum 41 // size of the fractional part is assumed to be 100. Thus, the 42 // maximum size of the string that would contain the number 43 // after conversion is safely assumed to be 420 (including any 44 // prefix, the null character and exponent specifiers 'e'). 45 // 46 // The buffers that contain the converted integer and the fraction parts of 47 // the float are safely assumed to be of size 310. 48 #define STD_DTOA_FORMAT_FLOAT_SIZE 420 49 #define STD_DTOA_FORMAT_INTEGER_SIZE 311 50 #define STD_DTOA_FORMAT_FRACTION_SIZE 100 51 52 // Constants for operations on the IEEE 754 representation of double 53 // precision floating point numbers. 54 #define STD_DTOA_DP_SIGN_SHIFT_COUNT 63 55 #define STD_DTOA_DP_EXPONENT_SHIFT_COUNT 52 56 #define STD_DTOA_DP_EXPONENT_MASK 0x7ff 57 #define STD_DTOA_DP_EXPONENT_BIAS 1023 58 #define STD_DTOA_DP_MANTISSA_MASK ( ( (uint64)1 << 52 ) - 1 ) 59 #define STD_DTOA_DP_INFINITY_EXPONENT_ID 0x7FF 60 #define STD_DTOA_DP_MAX_EXPONENT 1023 61 #define STD_DTOA_DP_MIN_EXPONENT_NORM -1022 62 #define STD_DTOA_DP_MIN_EXPONENT_DENORM -1074 63 #define STD_DTOA_DP_MAX_EXPONENT_DEC 308 64 #define STD_DTOA_DP_MIN_EXPONENT_DEC_DENORM -323 65 66 #define STD_DTOA_PRECISION_ROUNDING_VALUE 4 67 #define STD_DTOA_DEFAULT_FLOAT_PRECISION 6 68 69 #define STD_DTOA_NEGATIVE_INF_UPPER_CASE "-INF" 70 #define STD_DTOA_NEGATIVE_INF_LOWER_CASE "-inf" 71 #define STD_DTOA_POSITIVE_INF_UPPER_CASE "INF" 72 #define STD_DTOA_POSITIVE_INF_LOWER_CASE "inf" 73 #define STD_DTOA_NAN_UPPER_CASE "NAN" 74 #define STD_DTOA_NAN_LOWER_CASE "nan" 75 #define STD_DTOA_FP_POSITIVE_INF 0x7FF0000000000000uLL 76 #define STD_DTOA_FP_NEGATIVE_INF 0xFFF0000000000000uLL 77 #define STD_DTOA_FP_SNAN 0xFFF0000000000001uLL 78 #define STD_DTOA_FP_QNAN 0xFFFFFFFFFFFFFFFFuLL 79 80 // 81 // Useful Macros 82 // 83 84 #define MY_ISDIGIT(c) ( ( (c) >= '0' ) && ( (c) <= '9' ) ) 85 #define FP_EXPONENT(u) ( ( ( (u) >> STD_DTOA_DP_EXPONENT_SHIFT_COUNT ) \ 86 & STD_DTOA_DP_EXPONENT_MASK ) - STD_DTOA_DP_EXPONENT_BIAS ) 87 #define FP_EXPONENT_BIASED(u) ( ( (u) >> STD_DTOA_DP_EXPONENT_SHIFT_COUNT ) \ 88 & STD_DTOA_DP_EXPONENT_MASK ) 89 #define FP_MANTISSA_NORM(u) ( ( (u) & STD_DTOA_DP_MANTISSA_MASK ) | \ 90 ( (uint64)1 << STD_DTOA_DP_EXPONENT_SHIFT_COUNT ) ) 91 #define FP_MANTISSA_DENORM(u) ( (u) & STD_DTOA_DP_MANTISSA_MASK ) 92 #define FP_MANTISSA(u) ( FP_EXPONENT_BIASED(u) ? FP_MANTISSA_NORM(u) : \ 93 FP_MANTISSA_DENORM(u) ) 94 #define FP_SIGN(u) ( (u) >> STD_DTOA_DP_SIGN_SHIFT_COUNT ) 95 #define DOUBLE_TO_UINT64(d) ( *( (uint64*) &(d) ) ) 96 #define DOUBLE_TO_INT64(d) ( *( (int64*) &(d) ) ) 97 #define UINT64_TO_DOUBLE(u) ( *( (double*) &(u) ) ) 98 99 // 100 // Type Definitions 101 // 102 103 typedef enum 104 { 105 FP_TYPE_UNKOWN = 0, 106 FP_TYPE_NEGATIVE_INF, 107 FP_TYPE_POSITIVE_INF, 108 FP_TYPE_NAN, 109 FP_TYPE_GENERAL, 110 } FloatingPointType; 111 112 // 113 // Function Declarations 114 // 115 116 #ifdef __cplusplus 117 extern "C" { 118 #endif // #ifdef __cplusplus 119 120 double fp_pow_10( int nPow ); 121 double fp_round( double dNumber, int nPrecision ); 122 int fp_log_10( double dNumber ); 123 int fp_check_special_cases( double dNumber, FloatingPointType* pNumberType ); 124 int std_dtoa_decimal( double dNumber, int nPrecision, 125 char acIntegerPart[ STD_DTOA_FORMAT_INTEGER_SIZE ], 126 char acFractionPart[ STD_DTOA_FORMAT_FRACTION_SIZE ] ); 127 int std_dtoa_hex( double dNumber, int nPrecision, char cFormat, 128 char acIntegerPart[ STD_DTOA_FORMAT_INTEGER_SIZE ], 129 char acFractionPart[ STD_DTOA_FORMAT_FRACTION_SIZE ], 130 int* pnExponent ); 131 132 #ifdef __cplusplus 133 } 134 #endif // #ifdef __cplusplus 135 136 #endif // STD_DTOA_H 137 138