From d714a52cb6a96e4350bde8b39b6a58daa0afa629 Mon Sep 17 00:00:00 2001 From: James Stine Date: Tue, 1 Oct 2024 13:07:28 -0500 Subject: [PATCH 1/3] update fpcalc.c to match book and lex 0x or x prefix for inputs. Also improve the output for f128 to match half/single/double --- examples/fp/fpcalc/fpcalc.c | 42 ++++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/examples/fp/fpcalc/fpcalc.c b/examples/fp/fpcalc/fpcalc.c index 8264b1442..719fc72a6 100644 --- a/examples/fp/fpcalc/fpcalc.c +++ b/examples/fp/fpcalc/fpcalc.c @@ -224,8 +224,15 @@ __uint128_t strtoul128(char *num, int base) { } __uint128_t parseNum(char *num) { -// uint64_t result; + // uint64_t result; __uint128_t result; + + // Ensure input starts with "0x" or "x" + if (!(num[0] == '0' && num[1] == 'x') && !(num[0] == 'x')) { + printf("Error: Input must start with '0x' or 'x'\n"); + exit(1); + } + int size; // size of operands in bytes (2= half, 4=single, 8 = double) if (strlen(num) < 8) size = 2; else if (strlen(num) < 16) size = 4; @@ -244,7 +251,34 @@ __uint128_t parseNum(char *num) { opSize = size; //printf ("Operand size is %d\n", opSize); } - result = (__uint128_t)strtoul128(num, 16); + + // Add to handle either input preference + // Strip the "x" or "0x" prefixes if present + if (num[0] == 'x' || (num[0] == '0' && num[1] == 'x')) { + num += (num[0] == 'x') ? 1 : 2; + } + + if (strlen(num) <= 16) { + result = (__uint128_t)strtoull(num, NULL, 16); + } + else { + while (*num) { + int value; + if (*num >= '0' && *num <= '9') + value = *num - '0'; + else if (*num >= 'a' && *num <= 'f') + value = *num - 'a' + 10; + else if (*num >= 'A' && *num <= 'F') + value = *num - 'A' + 10; + else { + printf("Error: invalid character in input\n"); + exit(1); + } + result = (result << 4) | value; + num++; + } + } + //printf("Parsed %s as 0x%lx\n", num, result); return result; } @@ -387,8 +421,10 @@ int main(int argc, char *argv[]) } printF128("X", x); printF128("Y", y); //sprintf(cmd, "0x%016lx %c 0x%016lx", x.v, op1, y.v); + printf("0x%016" PRIx64 "_%016" PRIx64 " %c ", x.v[1], x.v[0], op1); + printf("0x%016" PRIx64 "_%016" PRIx64 " ", y.v[1], y.v[0]); printF128(cmd, r); printFlags(); - printF128val(r); + // printF128val(r); } } } From df2dd3f887e4ec59e3357cb7a93f6d2b2f0aba0b Mon Sep 17 00:00:00 2001 From: James Stine Date: Tue, 1 Oct 2024 13:09:36 -0500 Subject: [PATCH 2/3] update fpcalc.c to match book and lex 0x or x prefix for inputs. Also improve the output for f128 to match half/single/double --- examples/fp/fpcalc/fpcalc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/fp/fpcalc/fpcalc.c b/examples/fp/fpcalc/fpcalc.c index 719fc72a6..f317be6d9 100644 --- a/examples/fp/fpcalc/fpcalc.c +++ b/examples/fp/fpcalc/fpcalc.c @@ -249,7 +249,6 @@ __uint128_t parseNum(char *num) { } } else { opSize = size; - //printf ("Operand size is %d\n", opSize); } // Add to handle either input preference From bcd6f3da16fab2d8ee835c91681340080826c50d Mon Sep 17 00:00:00 2001 From: James Stine Date: Tue, 1 Oct 2024 15:46:35 -0500 Subject: [PATCH 3/3] update fpcalc to recognize 0x, x, or just hex --- examples/fp/fpcalc/fpcalc.c | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/examples/fp/fpcalc/fpcalc.c b/examples/fp/fpcalc/fpcalc.c index f317be6d9..16dcce225 100644 --- a/examples/fp/fpcalc/fpcalc.c +++ b/examples/fp/fpcalc/fpcalc.c @@ -224,20 +224,20 @@ __uint128_t strtoul128(char *num, int base) { } __uint128_t parseNum(char *num) { - // uint64_t result; - __uint128_t result; + __uint128_t result = 0; - // Ensure input starts with "0x" or "x" - if (!(num[0] == '0' && num[1] == 'x') && !(num[0] == 'x')) { - printf("Error: Input must start with '0x' or 'x'\n"); - exit(1); + // Ensure input is in correct form + if (num[0] == '0' && num[1] == 'x') { + num += 2; // Skip "0x" + } else if (num[0] == 'x') { + num += 1; // Skip "x" } - - int size; // size of operands in bytes (2= half, 4=single, 8 = double) + + int size; // size of operands in bytes (2= half, 4=single, 8 = double) if (strlen(num) < 8) size = 2; else if (strlen(num) < 16) size = 4; else if (strlen(num) < 32) size = 8; - else if (strlen(num) < 35) size = 16; // *** will need to increase + else if (strlen(num) < 35) size = 16; // *** will need to increase else { printf("Error: only half, single, double, or quad precision supported"); exit(1); @@ -246,17 +246,11 @@ __uint128_t parseNum(char *num) { if (size != opSize) { printf("Error: inconsistent operand sizes %d and %d\n", size, opSize); exit(1); - } + } } else { opSize = size; } - // Add to handle either input preference - // Strip the "x" or "0x" prefixes if present - if (num[0] == 'x' || (num[0] == '0' && num[1] == 'x')) { - num += (num[0] == 'x') ? 1 : 2; - } - if (strlen(num) <= 16) { result = (__uint128_t)strtoull(num, NULL, 16); } @@ -302,8 +296,7 @@ char parseRound(char *rnd) { } } -int main(int argc, char *argv[]) -{ +int main(int argc, char *argv[]) { //uint64_t xn, yn, zn; __uint128_t xn, yn, zn; char op1, op2;