Fixed point arithmetic in Pyteal

Last week I was lucky enough to go to ETHDenver and got to learn a ton of new developments in the Algorand Ecosystem, plus I got to know some brilliant people in the Algo ecosystem. I want to thank @barnji for showing me this repository for fixed-point arithmetic in Pyteal: pyteal-utils/fixed_point.py at fp-class · barnjamin/pyteal-utils · GitHub

I am having some trouble using the library in my code.

Goal: I want to divide two integers with a high degree of precision in order to get a percentage.

My code:

from pyteal import *
from .fp_arithmetic import fp_div, fp_mul, fp_to_ascii

def approval_program():

    @Subroutine(TealType.none)
    def divide_func():
       
        numerator = Int(90)
        denominator = Int(45000000000)

        numerator_bytes = Itob(numerator)
        denominator_bytes = Itob(denominator)

        division_result = fp_div(numerator_bytes, denominator_bytes)
        division_result_to_ascii = fp_to_ascii(division_result)

        return Seq([ 
            
            Log( division_result_to_ascii ),
            
        ])

The smart contract logs:

'0.'

What am I doing wrong?

1 Like

You dont want to use the utility functions directly here, you’d want to construct the floating point objects themselves.

Something like this (untested)

 bits = 64
 precision = 5
 numerator = FixedPoint(90, bits, precision)
 denominator = FixedPoint(45000000000, bits, precision)
 return Seq(
      Log(fp_to_ascii(numerator/denominator))
  )

Hey Ben! Thanks for the response.

When I divide 90 / 450, it seems to log the result just fine: .20000. However, when I make the denominator larger, for example: 90 / 4500, I get the following error:

AlgodHTTPError: TransactionPool.Remember: transaction JNDSSJLRMR3IOTCL4FFGVZUMX3M5DCVHVHOUF6B3Q5LM3UTVNEFA: logic eval error: - would result negative. Details: pc=393, opcodes=intc_1 // 0
getbyte
-

Any clues as to why that is happening?

Probably because it goes beyond the precision you set?