I have a very weird use case. Tl;dr I'm trying to convert a bytes16 to a base 10 integer by keeping the digits in tact.
i.e 0x00000000000000000000000002987391
should become 2987391
Ethereum Stack Exchange is a question and answer site for users of Ethereum, the decentralized application platform and smart contract enabled blockchain. It only takes a minute to sign up.
Sign up to join this communityAssuming all the hex numbers are between 0-9, you can use one of the two functions below (the first one is more gas efficient, while the second function is more human readable). The output can be reduced to uint112 if needed since the max number is 0x99999999999999999999999999999999
.
function hex2Base10Assembly (bytes16 input) public pure returns (uint output) {
uint power10 = 1;
assembly {
input := shr(128, input)
for { let i := 0 } lt(i, 31) { i := add(i, 1) } {
output := add(output, mul(mod(input, 16), power10))
input := div(input, 16)
power10 := mul(power10, 10)
}
output := add(output, mul(mod(input, 16), power10))
}
return output;
}
Human readable:
function hex2Base10 (bytes16 hexInput) public pure returns (uint output) {
uint power10 = 1;
uint128 input = uint128(hexInput);
for(uint i; i < 31; ++i) {
output = output + (input % 16) * power10;
input = input / 16;
power10 = power10 * 10;
}
output = output + (input % 16) * power10;
return output;
}