From 4ff6a08d73f0ef1e2fcb7a93a74cc6fa66c24e2b Mon Sep 17 00:00:00 2001 From: Joel Kronqvist Date: Sun, 7 Apr 2024 13:31:07 +0300 Subject: Bigger `bytes_read` & removed redundant code handling impossible signed `bytes_read` --- .gitignore | 1 + formatting.c | 265 +++++++++++++++-------------------------------------------- formatting.h | 35 +++++--- formatting.o | Bin 27848 -> 0 bytes intmath.c | 9 ++ intmath.h | 1 + stdu.c | 19 +++-- 7 files changed, 115 insertions(+), 215 deletions(-) delete mode 100644 formatting.o diff --git a/.gitignore b/.gitignore index cba0639..1e29060 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ stdu stdu.o intmath.o config-parser.o +formatting.o tests diff --git a/formatting.c b/formatting.c index c806f4d..ac0222c 100644 --- a/formatting.c +++ b/formatting.c @@ -1,4 +1,8 @@ +/* if ever in need of formatting functions like in this file, but signed, they + * can be found wasted in the version history, commit + * f975594e55bdc05ee436bc7bdcd6e09aec5357b1. */ + #include #include #include @@ -7,6 +11,7 @@ #include "formatting.h" #include "minitest.h" + size_t int_charcount(int x) { size_t n = x < 0; x *= -(x < 0) * 2 + 1; @@ -22,27 +27,17 @@ size_t int_charcount(int x) { * * `unsigned int base` affects the precision. */ -exp_notated int_floored_exponent_notation_base +exp_notated ull_floored_exponent_notation_base ( - int x, + unsigned long long x, unsigned int precision, unsigned int base ) { - int original = x; - int sign = (x < 0) * -2 + 1; - x *= sign; - int i = 0; while (x >= int_pown(base, precision)) { x /= base; i++; } - x += (sign == -1) && (original != -x * int_pown(base, i)); - if (x >= int_pown(base, precision)) { - x /= base; - i++; - } - x *= sign; exp_notated res = { .mantissa = x, @@ -52,26 +47,47 @@ exp_notated int_floored_exponent_notation_base return res; } -exp_notated int_floored_exponent_notation(int x, unsigned int precision) { - return int_floored_exponent_notation_base(x, precision, 10); +exp_notated ull_floored_exponent_notation( + unsigned long long x, + unsigned int precision +) { + return ull_floored_exponent_notation_base(x, precision, 10); } -exp_notated int_ceiled_exponent_notation_base( - int x, +exp_notated ull_ceiled_exponent_notation_base( + unsigned long long x, unsigned int precision, unsigned int base ) { - exp_notated res = int_floored_exponent_notation_base(-x, precision, base); - res.mantissa = -res.mantissa; + unsigned long long original = x; + + int i = 0; + while (x >= int_pown(base, precision)) { + x /= base; + i++; + } + + if (x * ull_pown(base, i) != original) { + x += 1; + } + + exp_notated res = { + .mantissa = x, + .exponent = i, + .base = base + }; return res; } -exp_notated int_ceiled_exponent_notation(int x, unsigned int precision) { - return int_ceiled_exponent_notation_base(x, precision, 10); +exp_notated ull_ceiled_exponent_notation( + unsigned long long x, + unsigned int precision +) { + return ull_ceiled_exponent_notation_base(x, precision, 10); } -int exp_notated_to_int(exp_notated x) { - return x.mantissa * int_pown(x.base, x.exponent); +unsigned long long exp_notated_to_ull(exp_notated x) { + return x.mantissa * (unsigned long long) int_pown(x.base, x.exponent); } /* Returns the appropriate binary prefix for `exp_notated x`. `x` must have @@ -110,20 +126,20 @@ const char* binary_prefix(exp_notated x) { } /* Modifies the string pointed to by `char** res` to a string describing the - * argument `int x` floored to the appropriate multiple of 1024 followed with a - * binary prefix (Ki, Mi, Gi...). + * argument `unsigned long long x` floored to the appropriate multiple of 1024 + * followed with a binary prefix (Ki, Mi, Gi...). * * `size_t* res_bufsize` should point to a value describing the size of the * string buffer pointed to by `char** res`. Returns a negative value upon * failure in memory allocation or `snprintf`, otherwise returns the length of * `char* res`. */ -int int_floored_with_binary_prefix(char** res, size_t* res_bufsize, int x) { - exp_notated x_exp = int_floored_exponent_notation_base(x, 1, 1024); - if (x_exp.exponent > 10) { /* quebi-=1024^10 greatest defined prefix */ - x_exp.mantissa *= int_pown(1024, x_exp.exponent - 10); - x_exp.exponent = 10; - } +int ull_floored_with_binary_prefix( + char** res, + size_t* res_bufsize, + unsigned long long x +) { + exp_notated x_exp = ull_floored_exponent_notation_base(x, 1, 1024); const char* prefix = binary_prefix(x_exp); @@ -138,7 +154,7 @@ int int_floored_with_binary_prefix(char** res, size_t* res_bufsize, int x) { *res_bufsize = bufsize; } if (*res == NULL) return -1; - return snprintf(*res, *res_bufsize, "%d %s", x_exp.mantissa, prefix); + return snprintf(*res, *res_bufsize, "%llu %s", x_exp.mantissa, prefix); } /* Returns the unit prefix resembling the exponent `int x`. If there is no @@ -211,14 +227,14 @@ const char* unit_prefix(int exponent) { * failure and the length of `char* res` on success. Failure can be caused by * problems in memory allocation or failure in `snprintf`. */ -int int_floored_with_prefix( +int ull_floored_with_prefix( char** res, size_t* res_bufsize, - int x, + long long unsigned x, unsigned int precision ) { exp_notated x_exp - = int_floored_exponent_notation_base(x, precision, 10); + = ull_floored_exponent_notation_base(x, precision, 10); double mantissa = (double) x_exp.mantissa * int_pow10(x_exp.exponent % 3); unsigned int exponent = x_exp.exponent - x_exp.exponent % 3; @@ -255,9 +271,9 @@ char* test_floored_exponent_notation() { const size_t bufsize = 128; char* msg = malloc(bufsize); - exp_notated res = int_floored_exponent_notation(9489345, 3); + exp_notated res = ull_floored_exponent_notation(9489345, 3); snprintf(msg, bufsize, - "int_floored_exponent_notation(9489345, 3): expected 948*10^4, got %d*%d^%d", + "ull_floored_exponent_notation(9489345, 3): expected 948*10^4, got %d*%d^%d", res.mantissa, res.base, res.exponent ); mt_assert( @@ -266,31 +282,9 @@ char* test_floored_exponent_notation() { res.exponent == 4 , msg); - res = int_floored_exponent_notation(-88, 1); + res = ull_floored_exponent_notation_base(3145733, 1, 1024); snprintf(msg, bufsize, - "int_floored_exponent_notation(-88, 1): expected -9*10^1, got %d*%d^%d", - res.mantissa, res.base, res.exponent - ); - mt_assert( - res.mantissa == -9 && - res.base == 10 && - res.exponent == 1 - , msg); - - res = int_floored_exponent_notation(-99, 1); - snprintf(msg, bufsize, - "int_floored_exponent_notation(-99, 1): expected -1*10^2, got %d*%d^%d", - res.mantissa, res.base, res.exponent - ); - mt_assert( - res.mantissa == -1 && - res.base == 10 && - res.exponent == 2 - , msg); - - res = int_floored_exponent_notation_base(3145733, 1, 1024); - snprintf(msg, bufsize, - "int_floored_exponent_notation_base(3145733, 1, 1024): expected 3*1024^2, got %d*%d^%d", + "ull_floored_exponent_notation_base(3145733, 1, 1024): expected 3*1024^2, got %d*%d^%d", res.mantissa, res.base, res.exponent ); mt_assert( @@ -299,39 +293,6 @@ char* test_floored_exponent_notation() { res.exponent == 2 , msg); - res = int_floored_exponent_notation_base(-1022, 1, 1024); - snprintf(msg, bufsize, - "int_floored_exponent_notation(-1022, 1, 1024): expected -1022*1024^0, got %d*%d^%d", - res.mantissa, res.base, res.exponent - ); - mt_assert( - res.mantissa == -1022 && - res.base == 1024 && - res.exponent == 0 - , msg); - - res = int_floored_exponent_notation_base(-1023, 1, 1024); - snprintf(msg, bufsize, - "int_floored_exponent_notation(-1023, 1, 1024): expected -1023*1024^0, got %d*%d^%d", - res.mantissa, res.base, res.exponent - ); - mt_assert( - res.mantissa == -1023 && - res.base == 1024 && - res.exponent == 0 - , msg); - - res = int_floored_exponent_notation_base(-1024, 1, 1024); - snprintf(msg, bufsize, - "int_floored_exponent_notation(-1024, 1, 1024): expected -1*1024^1, got %d*%d^%d", - res.mantissa, res.base, res.exponent - ); - mt_assert( - res.mantissa == -1 && - res.base == 1024 && - res.exponent == 1 - , msg); - free(msg); return 0; } @@ -340,9 +301,9 @@ char* test_ceiled_exponent_notation() { const size_t bufsize = 128; char* msg = malloc(bufsize); - exp_notated res = int_ceiled_exponent_notation(9489345, 3); + exp_notated res = ull_ceiled_exponent_notation(9489345, 3); snprintf(msg, bufsize, - "int_ceiled_exponent_notation(9489345, 3): expected 949*10^4, got %d*%d^%d", + "ull_ceiled_exponent_notation(9489345, 3): expected 949*10^4, got %d*%d^%d", res.mantissa, res.base, res.exponent ); mt_assert( @@ -351,31 +312,9 @@ char* test_ceiled_exponent_notation() { res.exponent == 4 , msg); - res = int_ceiled_exponent_notation(-99, 1); - snprintf(msg, bufsize, - "int_ceiled_exponent_notation(-99, 1): expected -9*10^1, got %d*%d^%d", - res.mantissa, res.base, res.exponent - ); - mt_assert( - res.mantissa == -9 && - res.base == 10 && - res.exponent == 1 - , msg); - - res = int_ceiled_exponent_notation(-100, 1); + res = ull_ceiled_exponent_notation_base(3145733, 1, 1024); snprintf(msg, bufsize, - "int_ceiled_exponent_notation(-100, 1): expected -1*10^2, got %d*%d^%d", - res.mantissa, res.base, res.exponent - ); - mt_assert( - res.mantissa == -1 && - res.base == 10 && - res.exponent == 2 - , msg); - - res = int_ceiled_exponent_notation_base(3145733, 1, 1024); - snprintf(msg, bufsize, - "int_ceiled_exponent_notation_base(3145733, 1, 1024): expected 4*1024^2, got %d*%d^%d", + "ull_ceiled_exponent_notation_base(3145733, 1, 1024): expected 4*1024^2, got %d*%d^%d", res.mantissa, res.base, res.exponent ); mt_assert( @@ -384,39 +323,17 @@ char* test_ceiled_exponent_notation() { res.exponent == 2 , msg); - res = int_ceiled_exponent_notation_base(-1023, 1, 1024); - snprintf(msg, bufsize, - "int_ceiled_exponent_notation(-1023, 1, 1024): expected -1023*1024^0, got %d*%d^%d", - res.mantissa, res.base, res.exponent - ); - mt_assert( - res.mantissa == -1023 && - res.base == 1024 && - res.exponent == 0 - , msg); - - res = int_ceiled_exponent_notation_base(-1024, 1, 1024); - snprintf(msg, bufsize, - "int_ceiled_exponent_notation(-1024, 1, 1024): expected -1*1024^1, got %d*%d^%d", - res.mantissa, res.base, res.exponent - ); - mt_assert( - res.mantissa == -1 && - res.base == 1024 && - res.exponent == 1 - , msg); - free(msg); return 0; } -char* test_exponent_notated_to_int() { +char* test_exponent_notated_to_ull() { exp_notated x = { .mantissa = 3, .exponent = 2, .base = 10 }; - mt_assert_eq(300, exp_notated_to_int(x)); + mt_assert_eq(300, exp_notated_to_ull(x)); return 0; } @@ -426,7 +343,7 @@ char* test_floored_with_binary_prefix() { size_t res_bufsize = 2; char* res = malloc(res_bufsize); - int_floored_with_binary_prefix( + ull_floored_with_binary_prefix( &res, &res_bufsize, 1026 @@ -437,29 +354,7 @@ char* test_floored_with_binary_prefix() { "1 Ki" ) == 0, msg); - int_floored_with_binary_prefix( - &res, - &res_bufsize, - -1023 - ); - snprintf(msg, bufsize, "-1023 yielded `%s` instead of `-1023`", res); - mt_assert(strcmp( - res, - "-1023 " - ) == 0, msg); - - int_floored_with_binary_prefix( - &res, - &res_bufsize, - -1026 - ); - snprintf(msg, bufsize, "-1026 yielded `%s` instead of `-2 Ki`", res); - mt_assert(strcmp( - res, - "-2 Ki" - ) == 0, msg); - - int_floored_with_binary_prefix( + ull_floored_with_binary_prefix( &res, &res_bufsize, 1049088 @@ -470,7 +365,7 @@ char* test_floored_with_binary_prefix() { "1 Mi" ) == 0, msg); - int_floored_with_binary_prefix( + ull_floored_with_binary_prefix( &res, &res_bufsize, 5243392 @@ -493,7 +388,7 @@ char* test_floored_with_prefix() { size_t res_bufsize = 2; char* res = malloc(res_bufsize); - int_floored_with_prefix( + ull_floored_with_prefix( &res, &res_bufsize, 1001, @@ -505,7 +400,7 @@ char* test_floored_with_prefix() { "1.00 k" ) == 0, msg); - int_floored_with_prefix( + ull_floored_with_prefix( &res, &res_bufsize, 300, @@ -517,31 +412,7 @@ char* test_floored_with_prefix() { "300 " ) == 0, msg); - int_floored_with_prefix( - &res, - &res_bufsize, - -999, - 3 - ); - snprintf(msg, bufsize, "-999 yielded `%s` instead of `-999 `", res); - mt_assert(strcmp( - res, - "-999 " - ) == 0, msg); - - int_floored_with_prefix( - &res, - &res_bufsize, - -1026, - 3 - ); - snprintf(msg, bufsize, "-1021 yielded `%s` instead of `-1.03 k`", res); - mt_assert(strcmp( - res, - "-1.03 k" - ) == 0, msg); - - int_floored_with_prefix( + ull_floored_with_prefix( &res, &res_bufsize, 1000000, @@ -553,7 +424,7 @@ char* test_floored_with_prefix() { "1.0 M" ) == 0, msg); - int_floored_with_prefix( + ull_floored_with_prefix( &res, &res_bufsize, 5243392, @@ -587,7 +458,7 @@ void formatting_tests() { mt_run_test(test_int_charcount); mt_run_test(test_floored_exponent_notation); mt_run_test(test_ceiled_exponent_notation); - mt_run_test(test_exponent_notated_to_int); + mt_run_test(test_exponent_notated_to_ull); mt_run_test(test_floored_with_binary_prefix); mt_run_test(test_floored_with_prefix); } diff --git a/formatting.h b/formatting.h index b9ef53b..1f96d35 100644 --- a/formatting.h +++ b/formatting.h @@ -3,28 +3,43 @@ #define FORMATTING_IS_IMPORTED struct exp_val { - int mantissa; + unsigned long long mantissa; int exponent; int base; }; typedef struct exp_val exp_notated; -exp_notated int_floored_exponent_notation_base( - int x, +exp_notated ull_floored_exponent_notation_base( + unsigned long long x, unsigned int precision, unsigned int base ); -exp_notated int_ceiled_exponent_notation_base( - int x, +exp_notated ull_ceiled_exponent_notation_base( + unsigned long long x, unsigned int precision, unsigned int base ); -exp_notated int_floored_exponent_notation(int x, unsigned int precision); -exp_notated int_ceiled_exponent_notation(int x, unsigned int precision); -int exp_notated_to_int(exp_notated x); +exp_notated ull_floored_exponent_notation( + unsigned long long x, + unsigned int precision +); +exp_notated ull_ceiled_exponent_notation( + unsigned long long x, + unsigned int precision +); +unsigned long long exp_notated_to_ull(exp_notated x); const char* binary_prefix(exp_notated x); const char* prefix(exp_notated x); -int int_floored_with_binary_prefix(char** res, size_t* res_bufsize, int x); -int int_floored_with_prefix(char** res, size_t* res_bufsize, int x, unsigned int precision); +int ull_floored_with_binary_prefix( + char** res, + size_t* res_bufsize, + unsigned long long x +); +int ull_floored_with_prefix( + char** res, + size_t* res_bufsize, + unsigned long long x, + unsigned int precision +); #endif diff --git a/formatting.o b/formatting.o deleted file mode 100644 index 709e87b..0000000 Binary files a/formatting.o and /dev/null differ diff --git a/intmath.c b/intmath.c index 5d70860..9e1f3ed 100644 --- a/intmath.c +++ b/intmath.c @@ -14,6 +14,15 @@ int int_pown(unsigned int base, unsigned int exp) { return res; } +unsigned long long ull_pown(unsigned int base, unsigned int exp) { + unsigned long long res = 1; + while (exp > 0) { + res *= base; + exp--; + } + return res; +} + int int_pow10(unsigned int exp) { return int_pown(10, exp); } diff --git a/intmath.h b/intmath.h index 810c221..5d0b56b 100644 --- a/intmath.h +++ b/intmath.h @@ -1,4 +1,5 @@ int int_pown(unsigned int base, unsigned int exp); +unsigned long long ull_pown(unsigned int base, unsigned int exp); int int_pow10(unsigned int exp); int int_floor(int x, int precision); int int_ceil(int x, int precision); diff --git a/stdu.c b/stdu.c index f2273f7..64f19a5 100644 --- a/stdu.c +++ b/stdu.c @@ -34,10 +34,11 @@ int main (int argc, char* argv[]) { int blocksize = 1; size_t bufsize = 1; - unsigned int bytes_read = 0; + int bufsize_tries = 10; + unsigned long long bytes_read = 0; size_t new_read_bytes = 0; if (conf->precision != 0) { - blocksize = exp_notated_to_int(int_ceiled_exponent_notation_base( + blocksize = exp_notated_to_ull(ull_ceiled_exponent_notation_base( bytes_read + 1, conf->precision, base)) @@ -55,14 +56,14 @@ int main (int argc, char* argv[]) { while (1) { /* output */ if (conf->human_readable && base == 10) { - int res = int_floored_with_prefix( + int res = ull_floored_with_prefix( &stdout_buffer, &stdout_buffer_size, bytes_read, conf->precision ); if (res < 0) { - printf("\r%u \ + printf("\r%llu \ (error when getting prefix)", bytes_read); continue; @@ -75,13 +76,13 @@ int main (int argc, char* argv[]) { previous_line_strlen = int_max(res, previous_line_strlen); } else if (conf->human_readable && base == 1024) { - int success = int_floored_with_binary_prefix( + int success = ull_floored_with_binary_prefix( &stdout_buffer, &stdout_buffer_size, bytes_read ); if (success < 0) { - printf("\r%u \ + printf("\r%llu \ (error when getting prefix)", bytes_read); } @@ -91,7 +92,7 @@ int main (int argc, char* argv[]) { stdout_buffer ); } else { - printf("\r%u", bytes_read); + printf("\r%llu", bytes_read); } if (fflush(stdout) == EOF) { printf("\n"); @@ -120,8 +121,9 @@ int main (int argc, char* argv[]) { /* resizing buffer and blocksize to read as much as possible * at once */ + if (bufsize_tries <= 0) continue; if (conf->precision == 0) continue; - blocksize = exp_notated_to_int(int_ceiled_exponent_notation_base( + blocksize = exp_notated_to_ull(ull_ceiled_exponent_notation_base( bytes_read + 1, conf->precision, base)) @@ -129,6 +131,7 @@ int main (int argc, char* argv[]) { if (blocksize > bufsize) { tmpbuf = malloc(bufsize * 2); if (tmpbuf == NULL) { + bufsize_tries--; free(tmpbuf); } else { free(buf); -- cgit v1.2.3