2

I have a solidity smart contract project that uses lots of floating point operations like Pow, ln, exp, etc, but I need more precision than normal 64 bit doubles. I am planning to use the ABDKMathQuad library which implements IEEE754 quadruple precision floating point numbers, which are stored as bytes16. I want to use a high level language to grab the bytes16 float value from the Ethereum block chain and display it as a decimal. Is there an easy way to do this? Here's my simple test code:

contract MyContract{

    using ABDKMathQuad for uint256;
    using ABDKMathQuad for int256;
    using ABDKMathQuad for bytes16;

    function get_float() public view returns(bytes16){
        uint256 int_numerator = 135335283236613;
        uint256 int_denominator = 1000000000000000;
        bytes16 float_numerator = int_numerator.fromUInt();
        bytes16 float_denominator = int_denominator.fromUInt();
        bytes16 float_result = float_numerator.div(float_denominator);
        return float_result; //returns 0.135335283236613 as a bytes16 data type
    }
}

get_float() returns:

{
    "0": "bytes16: 0x3ffc152aaa3bf81d6b9a230830957429"
}

I raised an issue with the creator of the ABDK library on github: https://github.com/abdk-consulting/abdk-libraries-solidity/issues/24

He provided me a nice toolkit for converting it manually: https://toolkit.abdk.consulting/math#convert-number

When I plug 0x3ffc152aaa3bf81d6b9a230830957429 into the toolkit, I get 0.135335283236612999999999999999999988

I want to use a high level language, preferably python, to do many such conversions of bytes16 to decimal so that I can debug easily. Is there an easy way to do this?

Thank you

1 Answer 1

1

I found a python library called anyfloat, which does exactly what I need.

I wrote a basic script using brownie and anyfloat:

from anyfloat import anyfloat
from decimal import Decimal

import brownie
from brownie import *
p = project.load('.', name="brownieTutorial")
p.load_config()
from brownie.project.brownieTutorial import *
network.connect('development')

def get_float(float_128):
    size = (15, 112)
    a = anyfloat.from_ieee(int(str(float_128), 16), size)
    f = a.to_fraction()
    dec = round(Decimal(f.numerator)/Decimal(f.denominator), 36)
    return dec

myContract = MyContract.deploy({"from": accounts[0]});
print('float value: ', get_float(myContract.get_float()))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.