aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--formatting.c265
-rw-r--r--formatting.h35
-rw-r--r--formatting.obin27848 -> 0 bytes
-rw-r--r--intmath.c9
-rw-r--r--intmath.h1
-rw-r--r--stdu.c19
7 files changed, 115 insertions, 215 deletions
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 <math.h>
#include <stdlib.h>
#include <string.h>
@@ -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
--- a/formatting.o
+++ /dev/null
Binary files 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);