aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomasz Kramkowski <tk@the-tk.com>2021-08-14 21:52:15 +0100
committerTomasz Kramkowski <tk@the-tk.com>2021-08-14 21:52:15 +0100
commit08c899ae66b20cd05dc6e15efc3ba7efb689e720 (patch)
tree53f83d4e57454ab27e6dd5fb1dc6befaca53516e
parenta46515fe7a31d72bb7f0130f7df9a9ca77a9b153 (diff)
downloadpack-08c899ae66b20cd05dc6e15efc3ba7efb689e720.tar.gz
pack-08c899ae66b20cd05dc6e15efc3ba7efb689e720.tar.xz
pack-08c899ae66b20cd05dc6e15efc3ba7efb689e720.zip
pack: Simplify signed integer packing calculation
Because of the fact that uintmax_t guarantees at least a full 64 bit width and because of C's behavior when a signed type is converted to an unsigned type and the value is out of range, the new code just sign-extends and converts to a uintmax_t wide two's complement signed value. As an aside, the old code was written forgetting the fact that that uintmax_t + intmax_t would be first converted to uintmax_t + uintmax_t before being evaluated. The end result was the same except it ended up being offset by 2^8s.
-rw-r--r--pack.c8
1 files changed, 1 insertions, 7 deletions
diff --git a/pack.c b/pack.c
index 4a8228a..5a603e0 100644
--- a/pack.c
+++ b/pack.c
@@ -59,13 +59,7 @@ enum pack_status pack(void *buf_, size_t size, const char *fmt, ...)
if (sign) {
intmax_t n = v.signed_;
tr_debug("val.s: %" PRIdMAX, v.signed_);
- if (v.signed_ >= 0) {
- v.unsigned_ = n;
- } else {
- uintmax_t offt = BITMASK(s * 8);
- n += 1;
- v.unsigned_ = offt + n;
- }
+ v.unsigned_ = n;
}
tr_debug("val.u: %" PRIuMAX, v.unsigned_);
write_val(&buf[offset], s, endianness, v.unsigned_);