diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2025-04-28 16:05:09 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2025-04-28 16:05:09 -0400 |
| commit | 9da5949b953ae5424afb77ff4280399eacf414d4 (patch) | |
| tree | 4db2b1ec3abe4f4e63d0fd57c3efbf588c8f92f4 /src/stdlib | |
| parent | a49610246e12d8e2947f8ce2bc981acbbb88a901 (diff) | |
Remove remaining printf references
Diffstat (limited to 'src/stdlib')
| -rw-r--r-- | src/stdlib/fpconv.h | 2 | ||||
| -rw-r--r-- | src/stdlib/integers.c | 7 | ||||
| -rw-r--r-- | src/stdlib/print.c | 102 | ||||
| -rw-r--r-- | src/stdlib/print.h | 7 |
4 files changed, 95 insertions, 23 deletions
diff --git a/src/stdlib/fpconv.h b/src/stdlib/fpconv.h index 360c1f96..1d3dd813 100644 --- a/src/stdlib/fpconv.h +++ b/src/stdlib/fpconv.h @@ -24,7 +24,7 @@ * int str_len = fpconv_dtoa(d, buf); * * buf[str_len] = '\0'; - * printf("%s", buf); + * puts(buf); * } * */ diff --git a/src/stdlib/integers.c b/src/stdlib/integers.c index 86cdeb56..7250e2a2 100644 --- a/src/stdlib/integers.c +++ b/src/stdlib/integers.c @@ -32,11 +32,10 @@ static inline Text_t _int64_to_text(int64_t n) char *p = &buf[19]; bool negative = n < 0; - if (n == 0) - *(p--) = '0'; - - for (; n > 0; n /= 10) + do { *(p--) = '0' + (n % 10); + n /= 10; + } while (n > 0); if (negative) *(p--) = '-'; diff --git a/src/stdlib/print.c b/src/stdlib/print.c index df10a54f..3270c765 100644 --- a/src/stdlib/print.c +++ b/src/stdlib/print.c @@ -14,11 +14,10 @@ public int _print_int(FILE *f, int64_t n) char *p = &buf[19]; bool negative = n < 0; - if (n == 0) - *(p--) = '0'; - - for (; n > 0; n /= 10) + do { *(p--) = '0' + (n % 10); + n /= 10; + } while (n > 0); if (negative) *(p--) = '-'; @@ -31,11 +30,10 @@ public int _print_uint(FILE *f, uint64_t n) char buf[21] = {[20]=0}; // Big enough for UINT64_MAX + '\0' char *p = &buf[19]; - if (n == 0) - *(p--) = '0'; - - for (; n > 0; n /= 10) + do { *(p--) = '0' + (n % 10); + n /= 10; + } while (n > 0); return fwrite(p + 1, sizeof(char), (size_t)(&buf[19] - p), f); } @@ -54,15 +52,16 @@ public int _print_hex(FILE *f, hex_format_t hex) } char buf[9] = {[8]='\0'}; // Enough space for FFFFFFFF + '\0' char *p = &buf[7]; - for (uint64_t n = hex.n; n > 0; n /= 16) { - uint8_t digit = n % 16; + do { + uint8_t digit = hex.n % 16; if (digit <= 9) *(p--) = '0' + digit; else if (hex.uppercase) *(p--) = 'A' + digit - 10; else *(p--) = 'a' + digit - 10; - } + hex.n /= 16; + } while (hex.n > 0); printed += (int)fwrite(p + 1, sizeof(char), (size_t)(&buf[7] - p), f); return printed; } @@ -72,18 +71,17 @@ public int _print_oct(FILE *f, oct_format_t oct) int printed = 0; if (!oct.no_prefix) printed += fputs("0o", f); if (oct.digits > 0) { - for (uint64_t n = oct.n; n > 0 && oct.digits > 0; n /= 8) { + for (uint64_t n = oct.n; n > 0 && oct.digits > 0; n /= 8) oct.digits -= 1; - } - for (; oct.digits > 0; oct.digits -= 1) { + for (; oct.digits > 0; oct.digits -= 1) printed += fputc('0', f); - } } char buf[12] = {[11]='\0'}; // Enough space for octal UINT64_MAX + '\0' char *p = &buf[10]; - for (uint64_t n = oct.n; n > 0; n /= 8) { - *(p--) = '0' + (n % 8); - } + do { + *(p--) = '0' + (oct.n % 8); + oct.n /= 8; + } while (oct.n > 0); printed += (int)fwrite(p + 1, sizeof(char), (size_t)(&buf[10] - p), f); return printed; } @@ -95,6 +93,74 @@ public int _print_double(FILE *f, double n) return (int)fwrite(buf, sizeof(char), (size_t)len, f); } +public int _print_hex_double(FILE *f, hex_double_t hex) +{ + if (hex.d != hex.d) + return fputs("NAN", f); + else if (hex.d == 1.0/0.0) + return fputs("INF", f); + else if (hex.d == -1.0/0.0) + return fputs("-INF", f); + else if (hex.d == 0.0) + return fputs("0.0", f); + + union { double d; uint64_t u; } bits = { .d = hex.d }; + + int sign = (bits.u >> 63) & 1ull; + int exp = (int)((bits.u >> 52) & 0x7FF) - 1023ull; + uint64_t frac = bits.u & 0xFFFFFFFFFFFFFull; + + char buf[25]; + char *p = buf; + + if (sign) *p++ = '-'; + *p++ = '0'; + *p++ = 'x'; + + uint64_t mantissa = (1ull << 52) | frac; // implicit 1 + int mantissa_shift = 52; + + while ((mantissa & 0xF) == 0 && mantissa_shift > 0) { + mantissa >>= 4; + mantissa_shift -= 4; + } + + uint64_t int_part = mantissa >> mantissa_shift; + *p++ = "0123456789abcdef"[int_part]; + + *p++ = '.'; + + while (mantissa_shift > 0) { + mantissa_shift -= 4; + uint64_t digit = (mantissa >> mantissa_shift) & 0xF; + *p++ = "0123456789abcdef"[digit]; + } + + *p++ = 'p'; + + if (exp >= 0) { + *p++ = '+'; + } else { + *p++ = '-'; + exp = -exp; + } + + char expbuf[6]; + int ei = 5; + expbuf[ei--] = '\0'; + do { + expbuf[ei--] = '0' + (exp % 10); + exp /= 10; + } while (exp && ei >= 0); + + ei++; + while (expbuf[ei]) + *p++ = expbuf[ei++]; + + *p = '\0'; + return fwrite(buf, sizeof(char), (size_t)(p - buf), f); +} + public int _print_char(FILE *f, char c) { #define ESC(e) "'\\" e "'" diff --git a/src/stdlib/print.h b/src/stdlib/print.h index 454ef6b8..9bd89aea 100644 --- a/src/stdlib/print.h +++ b/src/stdlib/print.h @@ -43,6 +43,11 @@ typedef struct { #define hex(x, ...) ((hex_format_t){.n=x, __VA_ARGS__}) typedef struct { + double d; +} hex_double_t; +#define hex_double(x, ...) ((hex_double_t){.d=x, __VA_ARGS__}) + +typedef struct { uint64_t n; bool no_prefix; int digits; @@ -76,6 +81,7 @@ int _print_int(FILE *f, int64_t x); int _print_uint(FILE *f, uint64_t x); int _print_double(FILE *f, double x); int _print_hex(FILE *f, hex_format_t hex); +int _print_hex_double(FILE *f, hex_double_t hex); int _print_oct(FILE *f, oct_format_t oct); PRINT_FN _print_float(FILE *f, float x) { return _print_double(f, (double)x); } PRINT_FN _print_pointer(FILE *f, void *p) { return _print_hex(f, hex((uint64_t)p)); } @@ -111,6 +117,7 @@ extern int Int$print(FILE *f, Int_t i); float: _print_float, \ double: _print_double, \ hex_format_t: _print_hex, \ + hex_double_t: _print_hex_double, \ oct_format_t: _print_oct, \ quoted_t: _print_quoted, \ string_slice_t: _print_string_slice, \ |
