Open figs999 opened 2 years ago
@turbolent
I think exp(x)
is not that useful. The return type of exp(x)
has to be UFix64
whose maximum value is 184467440737.09551616
.
loge(184467440737.09551616) = 25.940738811884
So exp(x)
would only work for x <= 25.940738811884
which won't be that useful.
Similar logic for pow(x,y)
if the return type is a UFix64
. So, we should probably restrict it to just integers base and exponents and keep the return type as Int
.
Yeah, we might want to consider adding larger fixed-point types (128, 256, ...), potentially even without a min/max and just a fixed scale ("UFix"/"Fix", like UInt
and Int
- question is what the scale would be).
yeah, agreed.
Do you see any issues in making the scale flexible for UFix
as well? Apart from it no longer being "Fixed point" :slightly_smiling_face:
Kind of like how big.Float
allows SetPrec
. Can have an upper limit on the scale such as 16 or 32 to ensure the computations are feasible.
let a = UFix.fromString("10000000000000.22222222", /*scale*/ 16);
For computation with different scales - say adding a UFix
with scale 8 with another with scale 16, we could choose the larger one.
Yeah, I guess that makes sense. It would be best to not reinvent the wheel here and find an existing design and implementation we could follow.
Solidity seems to have something similar - ufixedMxN
and fixedMxN
where M
is the total number of bits and N
is the scale: https://docs.soliditylang.org/en/latest/types.html#fixed-point-numbers.
Very early stage though and not available for any practical use yet.
M must be divisible by 8 and goes from 8 to 256 bits. N must be between 0 and 80, inclusive.
So they don't think users need more than 256 bits.
I couldn't find any other fixed point implementation.
I think we can do the following:
ufixed
which is an alias for ufixed128x18
. Same for Fix128
UFix<N>
- where N
is the scale (max can be 80 same as Solidity). We can make it part of the type as done in Solidity. May be we only allow operations such as Add
, Multiply
etc on the same type (the same value of N
). One could explicitly convert from UFix<x>
to UFix<y>
if x <= y
using some conversion function.Similarly for Fix*
.
Issue To Be Solved
Currently cadence does not support any mathematical operations more advanced than basic arithmetic. When making bonded curves or proportional staking calculations, additional operations are required.
Suggested Solution
Please add the following mathematical functions: ln(x), log(x,b), pow(x,y), sqrt(x), exp(x) Natural Logarithm, Logarithm with arbitrary base, power (x to the y), square root, and exponent (euler's-number to the x)
Functions needed for all applicable numeric types. Currently these functions are being implemented in cadence script by developers, which adds needless overhead to execution and introduces the risk of bugs in the math algorithms. It would be more efficient for the script execution runtime to use the math operators available in it's base language.
These would ideally be accessible as language built-in-functions, but could also be placed inside the Numeric types like min and max.
Pow(x,y) could be implemented via an operator, such as in other languages using "x^y" or "x**y".