float_utils.c

Include dependency graph for float_utils.c:

digraph { graph [bgcolor="#00000000"] node [shape=rectangle style=filled fillcolor="#FFFFFF" font=Helvetica padding=2] edge [color="#1414CE"] "1" [label="/__w/AtomVM/AtomVM/src/libAtomVM/float_utils.c" tooltip="/__w/AtomVM/AtomVM/src/libAtomVM/float_utils.c" fillcolor="#BFBFBF"] "2" [label="float_utils.h" tooltip="float_utils.h"] "5" [label="term_typedef.h" tooltip="term_typedef.h"] "12" [label="unlocalized.h" tooltip="unlocalized.h"] "14" [label="utils.h" tooltip="utils.h"] "6" [label="assert.h" tooltip="assert.h"] "9" [label="float.h" tooltip="float.h"] "8" [label="inttypes.h" tooltip="inttypes.h"] "7" [label="limits.h" tooltip="limits.h"] "10" [label="math.h" tooltip="math.h"] "13" [label="stdbool.h" tooltip="stdbool.h"] "3" [label="stddef.h" tooltip="stddef.h"] "4" [label="stdint.h" tooltip="stdint.h"] "15" [label="stdio.h" tooltip="stdio.h"] "16" [label="stdlib.h" tooltip="stdlib.h"] "11" [label="string.h" tooltip="string.h"] "1" -> "2" [dir=forward tooltip="include"] "1" -> "6" [dir=forward tooltip="include"] "1" -> "9" [dir=forward tooltip="include"] "1" -> "10" [dir=forward tooltip="include"] "1" -> "4" [dir=forward tooltip="include"] "1" -> "11" [dir=forward tooltip="include"] "1" -> "12" [dir=forward tooltip="include"] "1" -> "14" [dir=forward tooltip="include"] "2" -> "3" [dir=forward tooltip="include"] "2" -> "4" [dir=forward tooltip="include"] "2" -> "5" [dir=forward tooltip="include"] "5" -> "6" [dir=forward tooltip="include"] "5" -> "7" [dir=forward tooltip="include"] "5" -> "8" [dir=forward tooltip="include"] "5" -> "4" [dir=forward tooltip="include"] "12" -> "13" [dir=forward tooltip="include"] "12" -> "3" [dir=forward tooltip="include"] "12" -> "5" [dir=forward tooltip="include"] "14" -> "8" [dir=forward tooltip="include"] "14" -> "13" [dir=forward tooltip="include"] "14" -> "3" [dir=forward tooltip="include"] "14" -> "15" [dir=forward tooltip="include"] "14" -> "16" [dir=forward tooltip="include"] }

Defines

D64_SIGN UINT64_C(0x8000000000000000)
D64_EXP_MASK UINT64_C(0x7FF0000000000000)
D64_FRACT_MASK UINT64_C(0x000FFFFFFFFFFFFF)
D64_IMPLICIT_ONE UINT64_C(0x0010000000000000)
D64_EXP_POS 52
D64_EXP_BIAS 1075
DIYFP_FRACT_SIZE 64
D_1_LOG2_10 0.30102999566398114
MIN_TARGET_EXP -60
MASK32 UINT64_C(0xFFFFFFFF)
TWO_POW_53 9007199254740992.0
MIN(x, y) ((x) <= (y) ? (x) : (y))
MAX(x, y) ((x) >= (y) ? (x) : (y))
MIN_CACHED_EXP -348
CACHED_EXP_STEP 8

Typedefs

typedef struct diy_fp diy_fp

Functions

_Static_assert (sizeof(double)==sizeof(uint64_t), "double must be 64 bits")
_Static_assert (DBL_MANT_DIG==53, "double must be IEEE 754 binary64")
static inline uint64_t cast_u64(double d)
static int32_t cached_pow(int32_t exp, diy_fp *p)
static diy_fp minus(diy_fp x, diy_fp y)
static diy_fp multiply(diy_fp x, diy_fp y)
static diy_fp normalize_diy_fp(diy_fp n)
static diy_fp double2diy_fp(double d)
static int32_t largest_pow10(uint32_t n, int32_t n_bits, uint32_t *power)
static int32_t round_weed(char *buffer, int32_t len, uint64_t wp_W, uint64_t delta, uint64_t rest, uint64_t ten_kappa, uint64_t ulp)
static int32_t digit_gen(diy_fp low, diy_fp w, diy_fp high, char *buffer, int32_t *length, int32_t *kappa)
static int32_t grisu3(double v, char *buffer, int32_t *length, int32_t *d_exp)
static int32_t write_exponent(int32_t exp, char *dst)
static int fixup_g_format(char *buf, int len)
static int32_t dtoa_grisu3(double v, char *dst)
static void strip_trailing_zeros(char *buf, size_t *len)
int double_write_to_ascii_buf(double value, float_format_t format, int precision, char *buf)

Convert a finite double to an ASCII string.

Caller must ensure isfinite(value) is true. Output always uses ‘.’ as decimal separator regardless of locale.

buf must be at least DOUBLE_WRITE_TO_ASCII_BUF_LEN bytes.

Parameters:
  • value – the double to convert

  • format – output format

  • precision – digits after decimal point (ignored for FloatFormatShort)

  • buf – output buffer (at least DOUBLE_WRITE_TO_ASCII_BUF_LEN bytes)

Returns:

number of characters written (excluding null terminator), or -1 if the output was truncated

Variables

static const uint64_t pow_cache_fract[] = {UINT64_C(0xfa8fd5a0081c0288), UINT64_C(0xbaaee17fa23ebf76), UINT64_C(0x8b16fb203055ac76), UINT64_C(0xcf42894a5dce35ea), UINT64_C(0x9a6bb0aa55653b2d), UINT64_C(0xe61acf033d1a45df), UINT64_C(0xab70fe17c79ac6ca), UINT64_C(0xff77b1fcbebcdc4f), UINT64_C(0xbe5691ef416bd60c), UINT64_C(0x8dd01fad907ffc3c), UINT64_C(0xd3515c2831559a83), UINT64_C(0x9d71ac8fada6c9b5), UINT64_C(0xea9c227723ee8bcb), UINT64_C(0xaecc49914078536d), UINT64_C(0x823c12795db6ce57), UINT64_C(0xc21094364dfb5637), UINT64_C(0x9096ea6f3848984f), UINT64_C(0xd77485cb25823ac7), UINT64_C(0xa086cfcd97bf97f4), UINT64_C(0xef340a98172aace5), UINT64_C(0xb23867fb2a35b28e), UINT64_C(0x84c8d4dfd2c63f3b), UINT64_C(0xc5dd44271ad3cdba), UINT64_C(0x936b9fcebb25c996), UINT64_C(0xdbac6c247d62a584), UINT64_C(0xa3ab66580d5fdaf6), UINT64_C(0xf3e2f893dec3f126), UINT64_C(0xb5b5ada8aaff80b8), UINT64_C(0x87625f056c7c4a8b), UINT64_C(0xc9bcff6034c13053), UINT64_C(0x964e858c91ba2655), UINT64_C(0xdff9772470297ebd), UINT64_C(0xa6dfbd9fb8e5b88f), UINT64_C(0xf8a95fcf88747d94), UINT64_C(0xb94470938fa89bcf), UINT64_C(0x8a08f0f8bf0f156b), UINT64_C(0xcdb02555653131b6), UINT64_C(0x993fe2c6d07b7fac), UINT64_C(0xe45c10c42a2b3b06), UINT64_C(0xaa242499697392d3), UINT64_C(0xfd87b5f28300ca0e), UINT64_C(0xbce5086492111aeb), UINT64_C(0x8cbccc096f5088cc), UINT64_C(0xd1b71758e219652c), UINT64_C(0x9c40000000000000), UINT64_C(0xe8d4a51000000000), UINT64_C(0xad78ebc5ac620000), UINT64_C(0x813f3978f8940984), UINT64_C(0xc097ce7bc90715b3), UINT64_C(0x8f7e32ce7bea5c70), UINT64_C(0xd5d238a4abe98068), UINT64_C(0x9f4f2726179a2245), UINT64_C(0xed63a231d4c4fb27), UINT64_C(0xb0de65388cc8ada8), UINT64_C(0x83c7088e1aab65db), UINT64_C(0xc45d1df942711d9a), UINT64_C(0x924d692ca61be758), UINT64_C(0xda01ee641a708dea), UINT64_C(0xa26da3999aef774a), UINT64_C(0xf209787bb47d6b85), UINT64_C(0xb454e4a179dd1877), UINT64_C(0x865b86925b9bc5c2), UINT64_C(0xc83553c5c8965d3d), UINT64_C(0x952ab45cfa97a0b3), UINT64_C(0xde469fbd99a05fe3), UINT64_C(0xa59bc234db398c25), UINT64_C(0xf6c69a72a3989f5c), UINT64_C(0xb7dcbf5354e9bece), UINT64_C(0x88fcf317f22241e2), UINT64_C(0xcc20ce9bd35c78a5), UINT64_C(0x98165af37b2153df), UINT64_C(0xe2a0b5dc971f303a), UINT64_C(0xa8d9d1535ce3b396), UINT64_C(0xfb9b7cd9a4a7443c), UINT64_C(0xbb764c4ca7a44410), UINT64_C(0x8bab8eefb6409c1a), UINT64_C(0xd01fef10a657842c), UINT64_C(0x9b10a4e5e9913129), UINT64_C(0xe7109bfba19c0c9d), UINT64_C(0xac2820d9623bf429), UINT64_C(0x80444b5e7aa7cf85), UINT64_C(0xbf21e44003acdd2d), UINT64_C(0x8e679c2f5e44ff8f), UINT64_C(0xd433179d9c8cb841), UINT64_C(0x9e19db92b4e31ba9), UINT64_C(0xeb96bf6ebadf77d9), UINT64_C(0xaf87023b9bf0ee6b)}
static const int16_t pow_cache_b_exp[] = {-1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980, -954, -927, -901, -874, -847, -821, -794, -768, -741, -715, -688, -661, -635, -608, -582, -555, -529, -502, -475, -449, -422, -396, -369, -343, -316, -289, -263, -236, -210, -183, -157, -130, -103, -77, -50, -24, 3, 30, 56, 83, 109, 136, 162, 189, 216, 242, 269, 295, 322, 348, 375, 402, 428, 455, 481, 508, 534, 561, 588, 614, 641, 667, 694, 720, 747, 774, 800, 827, 853, 880, 907, 933, 960, 986, 1013, 1039, 1066}
static const int16_t pow_cache_d_exp[] = {-348, -340, -332, -324, -316, -308, -300, -292, -284, -276, -268, -260, -252, -244, -236, -228, -220, -212, -204, -196, -188, -180, -172, -164, -156, -148, -140, -132, -124, -116, -108, -100, -92, -84, -76, -68, -60, -52, -44, -36, -28, -20, -12, -4, 4, 12, 20, 28, 36, 44, 52, 60, 68, 76, 84, 92, 100, 108, 116, 124, 132, 140, 148, 156, 164, 172, 180, 188, 196, 204, 212, 220, 228, 236, 244, 252, 260, 268, 276, 284, 292, 300, 308, 316, 324, 332, 340}
static const uint32_t pow10_cache[] = {0, 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000}
struct diy_fp

Public Members

uint64_t f
int32_t e