diff options
author | Tomasz Kramkowski <tk@the-tk.com> | 2021-08-14 21:52:15 +0100 |
---|---|---|
committer | Tomasz Kramkowski <tk@the-tk.com> | 2021-08-14 21:52:15 +0100 |
commit | 08c899ae66b20cd05dc6e15efc3ba7efb689e720 (patch) | |
tree | 53f83d4e57454ab27e6dd5fb1dc6befaca53516e | |
parent | a46515fe7a31d72bb7f0130f7df9a9ca77a9b153 (diff) | |
download | pack-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.c | 8 |
1 files changed, 1 insertions, 7 deletions
@@ -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_); |