Fixed point arithmetic in Pyteal - General - Algorand

Fixed point arithmetic in Pyteal

post by javier0rosas on Feb 21, 2022

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?

post by Ben on Feb 22, 2022

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))
  )

post by javier0rosas on Feb 22, 2022

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?

post by Ben on Feb 22, 2022

Probably because it goes beyond the precision you set?