aboutsummaryrefslogtreecommitdiff
path: root/src/stdlib
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-04-28 16:05:09 -0400
committerBruce Hill <bruce@bruce-hill.com>2025-04-28 16:05:09 -0400
commit9da5949b953ae5424afb77ff4280399eacf414d4 (patch)
tree4db2b1ec3abe4f4e63d0fd57c3efbf588c8f92f4 /src/stdlib
parenta49610246e12d8e2947f8ce2bc981acbbb88a901 (diff)
Remove remaining printf references
Diffstat (limited to 'src/stdlib')
-rw-r--r--src/stdlib/fpconv.h2
-rw-r--r--src/stdlib/integers.c7
-rw-r--r--src/stdlib/print.c102
-rw-r--r--src/stdlib/print.h7
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, \