# The most gas-efficient way to convert msg.data to int128?

Is there any more gas-efficient way to convert `msg.data` to `int128`?

Here is some suggested impl:

``````function bytesToBytes16(bytes b, uint offset) private pure returns (bytes16) {
bytes16 out;

for (uint i = 0; i < 16; i++) {
out |= bytes16(b[offset + i] & 0xFF) >> (i * 8);
}
return out;
}

...
int128 id = int128(bytesToBytes16(msg.data, 0));
``````

Any assembler alternative available?

• I think that even without assembly you could (at least slightly) improve this, by converting to `int128` directly. First, declare `out` as such. Second, on every iteration do `out |= int128(b[offset + i]) << (i * 8)`. Commented Aug 20, 2018 at 14:00
• Though I haven't tested this to make sure that Solidity compiler can handle the casting of a `bytes` entry into `int128`. Commented Aug 20, 2018 at 14:02
• `int128(msg.data)` does not work: `TypeError: Explicit type conversion not allowed from "bytes calldata" to "int128". int128 k = int128(msg.data);` Commented Aug 20, 2018 at 17:57

This should work

``````function foo(bytes m) public pure returns (uint128) {
bytes32 b;
assembly {
}
return uint128(b);
}
``````

The idea is to load the 16 bytes preceding our data, and use the truncation from bytes32 to uint128 to discard those first bytes.

Also be aware that `msg.data` includes the function signature and is encoded using the solidity ABI.

• is it correct that if transaction is sent using mist or myetherwallet.com with data typed manually there will be no function signature (i believe) - just data. So how should your code snippet be changed then? Commented Aug 22, 2018 at 4:26
• I tried invoking a function from remix and it includes the function signature. If you are just sending to the contract in the 'extra data' field and processing in the fallback function then yes, it will be just your data, because you are not calling a function directly.
– Ismael
Commented Aug 22, 2018 at 14:10
• in your code snippet you don't skip first 4 bytes for function? so it will work for direct transfer (what i need), right? Commented Aug 22, 2018 at 18:01
• BTW shouldn't it be `bytes16 b`? as 128 is 16 bytes Commented Aug 22, 2018 at 18:40
• @4ntoine My snippet do not skip over the first 4 bytes, `mload()` return 32 bytes I don't know if it is safe to assign it to a bytes16.
– Ismael
Commented Aug 22, 2018 at 19:54