Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-09 07:49:18

0001 //https://stackoverflow.com/questions/2437283/c-c-packing-signed-char-into-int
0002 
0003 #include <stdint.h>
0004 #include <iostream>
0005 #include <iomanip>
0006 
0007 // bits of signed integers can be carried within unsigned ones without problem
0008 uint32_t pack_helper(uint32_t c0, uint32_t c1, uint32_t c2, uint32_t c3) {
0009     return c0 | (c1 << 8) | (c2 << 16) | (c3 << 24);
0010 }
0011 
0012 uint32_t pack(uint8_t c0, uint8_t c1, uint8_t c2, uint8_t c3) {
0013     return pack_helper(c0, c1, c2, c3);
0014 }
0015 
0016 template <int N>
0017 uint8_t unpack_u(uint32_t packed) {   // cast to avoid potential warnings for implicit narrowing conversion
0018     return static_cast<uint8_t>(packed >> (N*8));
0019 }
0020 
0021 template <int N>
0022 int8_t unpack_s(uint32_t packed) {
0023     uint8_t r = unpack_u<N>(packed);
0024     return (r <= 0x7f ? r : r - 0x100 );   // b0111 = x7,   0x7f = 127, 0x100 = 256 
0025 }
0026 
0027 /**
0028 https://en.wikipedia.org/wiki/Two%27s_complement
0029 
0030 The two's complement of an N-bit number is defined as its complement with respect to 2^N = 0x1 << N ; (one bit past the end) 
0031 the sum of a number and its two's complement is 2^N = 0x1 << N 
0032 
0033 **/
0034 
0035 
0036 int main() {
0037 
0038     int x0 = 254 ; 
0039     int y0 = 127 ; 
0040     int z0 = -128 ; 
0041     int w0 = -7 ; 
0042 
0043     uint32_t pk = pack(x0,y0,z0,w0);
0044 
0045     int x1u = (int)unpack_u<0>(pk) ; 
0046     int y1u = (int)unpack_u<1>(pk) ; 
0047     int z1u = (int)unpack_u<2>(pk) ; 
0048     int w1u = (int)unpack_u<3>(pk) ; 
0049 
0050     int x1s = (int)unpack_s<0>(pk) ; 
0051     int y1s = (int)unpack_s<1>(pk) ; 
0052     int z1s = (int)unpack_s<2>(pk) ; 
0053     int w1s = (int)unpack_s<3>(pk) ; 
0054 
0055 
0056     std::cout 
0057         << std::setw(10) << x0 
0058         << std::setw(10) << x1u
0059         << std::setw(10) << x1s
0060         << std::endl 
0061         << std::setw(10) << y0 
0062         << std::setw(10) << y1u
0063         << std::setw(10) << y1s
0064         << std::endl 
0065         << std::setw(10) << z0 
0066         << std::setw(10) << z1u
0067         << std::setw(10) << z1s
0068         << std::endl 
0069         << std::setw(10) << w0 
0070         << std::setw(10) << w1u
0071         << std::setw(10) << w1s
0072         << std::endl 
0073         ;
0074 
0075     return 0 ; 
0076 }
0077 
0078 // clang SignedIntPackTest.cc -lc++ -o /tmp/SignedIntPackTest &&  /tmp/SignedIntPackTest