Skip to content

Instantly share code, notes, and snippets.

@3sGgpQ8H
Last active September 25, 2021 13:48
Show Gist options
  • Save 3sGgpQ8H/3659692206fe1bbd51f5ed92f7862566 to your computer and use it in GitHub Desktop.
Save 3sGgpQ8H/3659692206fe1bbd51f5ed92f7862566 to your computer and use it in GitHub Desktop.
pragma solidity ^0.7.0;
contract Utils64x64 {
/**
* Convert a 64.64 binary fixed point number into decimal string representation.
*/
function toDecimal (int128 x) public pure returns (string memory result) {
uint256 absX = uint (x >= 0 ? x : -int(x));
uint fracX = (absX & 0xFFFFFFFFFFFFFFFF) * 1e20 + 0x8000000000000000 >> 64;
uint f;
f = fracX % 10; fracX /= 10;
f |= fracX % 10 << 8; fracX /= 10;
f |= fracX % 10 << 16; fracX /= 10;
f |= fracX % 10 << 24; fracX /= 10;
f |= fracX % 10 << 32; fracX /= 10;
f |= fracX % 10 << 40; fracX /= 10;
f |= fracX % 10 << 48; fracX /= 10;
f |= fracX % 10 << 56; fracX /= 10;
f |= fracX % 10 << 64; fracX /= 10;
f |= fracX % 10 << 72; fracX /= 10;
f |= fracX % 10 << 80; fracX /= 10;
f |= fracX % 10 << 88; fracX /= 10;
f |= fracX % 10 << 96; fracX /= 10;
f |= fracX % 10 << 104; fracX /= 10;
f |= fracX % 10 << 112; fracX /= 10;
f |= fracX % 10 << 120; fracX /= 10;
f |= fracX % 10 << 128; fracX /= 10;
f |= fracX % 10 << 136; fracX /= 10;
f |= fracX % 10 << 144; fracX /= 10;
f |= fracX % 10 << 152; fracX /= 10;
uint fl = 20;
if (f << 128 == 0) { f >>= 128; fl -= 16; }
if (f << 192 == 0) { f >>= 64; fl -= 8; }
if (f << 224 == 0) { f >>= 32; fl -= 4; }
if (f << 240 == 0) { f >>= 16; fl -= 2; }
if (f << 248 == 0) { f >>= 8; fl -= 1; }
if (fl > 20) fl = 1;
f += 0x003030303030303030303030303030303030303030;
f <<= 256 - (fl << 3);
uint intX = absX >> 64;
uint i = 0;
i = intX % 10; intX /= 10;
i |= intX % 10 << 8; intX /= 10;
i |= intX % 10 << 16; intX /= 10;
i |= intX % 10 << 24; intX /= 10;
i |= intX % 10 << 32; intX /= 10;
i |= intX % 10 << 40; intX /= 10;
i |= intX % 10 << 48; intX /= 10;
i |= intX % 10 << 56; intX /= 10;
i |= intX % 10 << 64; intX /= 10;
i |= intX % 10 << 72; intX /= 10;
i |= intX % 10 << 80; intX /= 10;
i |= intX % 10 << 88; intX /= 10;
i |= intX % 10 << 96; intX /= 10;
i |= intX % 10 << 104; intX /= 10;
i |= intX % 10 << 112; intX /= 10;
i |= intX % 10 << 120; intX /= 10;
i |= intX % 10 << 128; intX /= 10;
i |= intX % 10 << 136; intX /= 10;
i |= intX % 10 << 144; intX /= 10;
uint il = 32;
if (i >> 128 == 0) { i <<= 128; il -= 16; }
if (i >> 192 == 0) { i <<= 64; il -= 8; }
if (i >> 224 == 0) { i <<= 32; il -= 4; }
if (i >> 240 == 0) { i <<= 16; il -= 2; }
if (i >> 248 == 0) { i <<= 8; il -= 1; }
i += 0x3030303030303030303030303030303030303000000000000000000000000000;
if (x < 0) {
i = i >> 8 | 0x2D00000000000000000000000000000000000000000000000000000000000000;
il += 1;
}
result = new string (il + fl + 1);
assembly {
let ptr := add (result, 0x20)
mstore (ptr, i)
ptr := add (ptr, il)
mstore (ptr, '.')
mstore (add (ptr, 1), f)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment