# What is the most gas efficient way to get the value of a bit in an unsigned integer?

Say I have an `uint16 _16bits` with binary value `1110_1011_0001_0001`, what would be the most gas efficient operation to get the value of any particular index in the range of `[0, 15]`?

For clarity:

``````using LowGasOperator for uint16;

_16bits.getValue(0) == 1
_16bits.getValue(1) == 0
``````

What would be the most gas efficient definition of `LowGasOperator.getValue`?

I did some test with `solc: 0.8.10+commit.fc410830.Emscripten.clang` and the optimizer enabled (`200` runs), and I came up with a function that is 45% less expensive than the double shift one you proposed:

``````// Gas cost: 103
function getValue(uint four_nibbles, uint mask) public pure returns (uint) {
return (four_nibbles & mask) > 0 ? 1 : 0;
}
``````

To squeeze a lot more you can do this:

``````// Gas cost: 27
function getValue(uint four_nibbles, uint mask) public pure returns (bool) {
return (four_nibbles & mask) > 0;
}
``````

These functions use a bitwise AND operator (`&`) with a mask instead of an index, so for example to get the 1st bit you pass `1`, the 2nd bit you pass `2`, the 3rd bit you pass `4`, the 4th bit you pass `8`, and so on.

Please note that using `unit16` and in general, any `uint` smaller than 256 bits, can easily increase the cost of the overall operations. The EVM always works with variables made of 256 bits, so when you use different sizes you introduce a surplus of work, and the gain from using smaller numbers rarely compensates for the added work. Check always on the field if the cost is really reduced.

For example in your specific case, the double shift function costs `188` gas with `uint16` and it costs `142` gas with `uint` (that is an alias for `uint256`):

``````// Gas cost: 142
function getValue(uint four_nibbles, uint index) public pure returns (uint) {
return (four_nibbles << (255 - index)) >> 255;
}

// Gas cost: 188
function getValue(uint16 four_nibbles, uint16 index) public pure returns (uint16) {
return (four_nibbles << (15 - index)) >> 15;
}
``````

I created a dedicated repo for you if you want to test it by yourself. Please don't take it as an example of good programming, it is just a very raw and fast way to test gas costs ;)

• How does using modifier view instead of pure effects the gas price? Example: function getValue(uint16 four_nibbles, uint16 index) public view returns (uint16) Could you test it quick?
– Sky
Jan 10 at 10:08
• "View" it's not needed if you don't access storage variables. In your case, you don't use storage so "pure" is the correct and cheapest way to do it. If you try to use "view", Solidity compiler is smart enough to avoid it anyway in the compiled bytecode, so the costs remain actually the same. I don't suggest to do it anyway, because using view you are almost "lying" to the developer that read the source code and cannot read the assembly. In the best case the reader see that view modifier as an error, at worst he thinks your method will access the storage in some way he don't understand. Jan 10 at 23:46
• I created a repo for you if you want to test more by yourself: github.com/InternetOfPeers/test-gas-costs Jan 10 at 23:54
• Thanks, I will try to read more on it to better get the point.
– Sky
Jan 11 at 7:52

I'm not sure why I didn't think of this earlier, but the function below does exactly what I want(though I'm not sure if it's the most gas efficient way of doing it). So I basically shake off all the bits to the left of the desired bit by shifting the desired bit to the 15-bit position(0-indexed), then I shake off all the bits to the right of the desired bit by shifting the desired bit to the 0-bit position.

``````function getValue(uint16 four_nibbles, uint16 index) public pure returns(uint16) {
return (four_nibbles << (15 - index)) >> 15;
}
``````