# Is it possible to pack two uintX into uint2X?

For example, for two `uint16` values, is it possible to concatenate them into one `uint32` value and also retrieve the original value later (bitwise operators)?

Please note that I do not mean addition by typecasting the 16 bit value to a 32 bit value and adding them together (`+`). But packing two 16 bit values into a 32 bit value.

``````           A                  B
|                  |
mapping (uint16 => mapping (uint16 => bool)) data;
``````

I can do this:

``````    (A << 16) | B
|
mapping (uint32 => bool) data;
``````

You need to use bit shifting operations:

``````pragma solidity^0.4.11;

contract Packing {

function pack(uint16 a, uint16 b) public pure returns(uint32) {
return (uint32(a) << 16) | uint32(b);
}

function unpack(uint32 c) public pure returns(uint16 a, uint16 b) {
a = uint16(c >> 16);
b = uint16(c);
}
}
``````

Note however that the Solidity compiler will do packing of state variables for you if you use the `--optimize` flag for `solc`. For example, in the following contract the compiler will generate the code that uses a single storage slot although there are 4 state variables (64 * 4 = 256bits = 32 bytes):

``````pragma solidity ^0.4.11;

contract C {
uint64 a;
uint64 b;
uint64 c;
uint64 d;

function C() {
a = 0xaaaa;
b = 0xbbbb;
c = 0xcccc;
d = 0xdddd;
}
}
``````

You can test if the compiler will also do packing for mappings as in your case.

• Thanks. Is there a reason why you use the + instead of the | operator? Yes, I will have to analyze whether packing for a mapping index is actually more efficient. – Elias Feb 7 '18 at 10:20
• @Elias No reason. In this case both can be used and they are equally efficient in terms of gas as they cost 3 gas. I believe | is more efficient in terms of cpu cycles so I changed my answer. – medvedev1088 Feb 7 '18 at 10:34

Yes you can do. If you want to add to 16 bytes integers there might be a chance of overflow of values which may leads to be unexpected results.

Then solution is convert uint16 bytes to 32 bytes or grater than 16 bytes just by adding uint18 or more. I'll prefer to convert 32 bytes.

Converting uint12 bytes to X bytes is `uintX(value)` now replace x with 32. so final result is `uint32(value)`

``````pragma solidity ^0.4.19;

contract Example {

uint16 a = 256;
uint16 b = 256;

function add() external view returns (uint32 c) {
c = uint32(a) + uint32(b); //uint18(a)+uint18(b)
}
}
``````