wadray 0.5.0
Fixed-point decimal numbers for Cairo
This library implements two types of fixed-point decimal numbers, "wad" (18 decimals of precision) and "ray" (27 decimals of decimal numbers), available in signed (SignedWad
and SignedRay
) and unsigned (Wad
and Ray
) versions, written in Cairo for Starknet.
Wad
and Ray
are implemented as structs with a single u128
member for the value, while SignedWad
and SignedRay
are implemented as structs with a u128
member for the value and bool
member for the sign
(i.e. if the sign
is true
, then the value is negative).
This library includes arithmetic, comparison and conversion functions.
Addition and subtraction can be performed via the Add
, AddEq
, Sub
and SubEq
traits as follows:
a + b
a += b
a - b
a -= b
where both a
and b
are of the same type.
Multiplication and division can be performed via the the Mul
, MulEq
, Div
and DivEq
traits as follows:
a * b
a *= b
a / b
a /= b
where both a
and b
are of the same type.There is also a set of functions for operations involving a Wad
and a Ray
:
wmul_wr
/wmul_rw
: Multiply a Wad
value with a Ray
value, and divide the product by one Wad
scale to return a Ray
wdiv_rw
: Scale up a Ray
value by one Wad
scale and divide the scaled value by a Wad
value to return a Ray
rmul_wr
/rmul_rw
: Multiply a Wad
value with a Ray
value, and divide the product by one Ray
scale to return a Wad
rdiv_wr
: Scale up a Wad
value by one Ray
scale and divide the scaled value by a Ray
to return a Wad
rdiv_ww
: Scale up a Wad
value by one Ray
scale and divide the scaled value by a Wad
to return a Ray
For multiplication, the prefixes w
and r
denote whether the product is divided (i.e. scaled down) by a Wad
or Ray
respectively. For division, the prefixes w
and r
denote whether the first operand is multiplied (i.e. scaled up) by a Wad
or Ray
before the division respectively.
As these are fixed point operations, do take note that there will be a loss of precision.
Zero and one valuesThe following values and functions for both Wad
and Ray
, and SignedWad
and SignedRay
, are available via the Zeroable
and Oneable
traits.
WadZeroable::zero()
/RayZeroable::zero()
: Returns the zero value for Wad
and Ray
respectivelyis_zero()
: Returns true if the Wad
or Ray
value is zerois_non_zero()
Returns true if the Wad
or Ray
value is not zeroWadOneable::one()
/RayOneable::one()
: Returns the scale value for Wad
(i.e. 1018) and Ray
(i.e. 1027) respectivelyis_one()
: Returns true if the Wad
or Ray
value is the scale value (i.e. 1018 and 1027 respectively)is_non_one()
Returns true if the Wad
or Ray
value is not the scale value (i.e. 1018 and 1027 respectively)SignedWadZeroable::zero()
/SignedRayZeroable::zero()
: Returns the zero value for Wad
and Ray
respectivelyis_zero()
: Returns true if the SignedWad
or SignedRay
value is zero, regardless of the sign
.is_non_zero()
Returns true if the SignedWad
or SignedRay
value is not zeroSignedWadOneable::one()
/SignedRayOneable::one()
: Returns the positive scale value for "wad" (i.e. 1018) and "ray" (i.e. 1027) respectivelyis_one()
: Returns true if the SignedWad
or SignedRay
value is the positive scale value (i.e. 1018 and 1027 respectively)is_non_one()
Returns true if the SignedWad
or SignedRay
value is not the positive scale value (i.e. 1018 and 1027 respectively)The bound values for both Wad
and Ray
can be obtained via the BoundedInt
trait.
BoundedWad::max()
: Returns the maximum Wad
value of 2128 - 1BoundedWad::min()
: Returns the minimum Wad
value of 0BoundedRay::max()
: Returns the maximum Ray
value of 2128 - 1BoundedRay::min()
: Returns the minimum Ray
value of 0Comparison for both Wad
and Ray
, and SignedWad
and SignedRay
, can be performed via the PartialEq
and PartialOrd
traits as follows:
a == b
a != b
a > b
a >= b
a < b
a <= b
where both a
and b
are of the same type.
Any type that can be converted to a u128
via the Into
trait can similarly be converted to a Wad
or Ray
via the Into
trait.
Additionally, the following conversions from integer types are supported for SignedWad
and SignedRay
via the Into
trait`:
u128
-> SignedWad
: Convert a u128
to a SignedWad
without modifying the value, with the sign
set to false
u128
-> SignedRay
: Convert a u128
to a SignedRay
without modifying the value, with the sign
set to false
The following conversions from this library's types can also be performed via the Into
trait:
Wad
-> felt252
: Convert a Wad
to a felt252
without modifying the valueWad
-> u256
: Convert a Wad
to a u256
without modifying the valueWad
-> SignedWad
: Convert a Wad
to a SignedWad
without modifying the value, with the sign
set to false
Ray
-> SignedRay
: Convert a Ray
to a SignedRay
without modifying the value, with the sign
set to false
SignedWad
-> felt252
: Convert a SignedWad
to a felt252
without modifying the valueSignedRay
-> felt252
: Convert a SignedRay
to a felt252
without modifying the valueThe following conversions can be performed via the TryInto
trait:
u256
-> Option::<Wad>
: Returns Option::Some<Wad>
if the value is within bounds of u128
or Option::None
otherwiseSignedWad
-> Option::<Wad>
: Returns Option::Some<Wad>
if sign
is false or Option::None
otherwiseSignedRay
-> Option::<Ray>
: Returns Option::Some<Ray>
if sign
is false or Option::None
otherwiseThe following functions can be used to scale between Wad
and Ray
:
fn ray_to_wad(x: Ray) -> Wad
: Divide the Ray
value by 109 and return a Wad
fn wad_to_ray(x: Wad) -> Option::<Ray>
: Multiply the Wad
value by 109 and return Option::Some<Ray>
if there is no overflow or Option::None
otherwiseWad
and Ray
Overview
Starting from v0.5.0
of this library, we have made significant changes to how Wad
values are converted to Ray
values and vice versa. This aims to improve type safety and align with the semantics of Rust's Into
trait.
Into<Wad, Ray>
scaled the value by 109 while Into<Ray, Wad>
scaled the value by 10-9. Both now perform direct type cast without value modificationwad_to_ray()
and ray_to_wad()
functions for value-preserving conversionswad_to_ray()
and ray_to_wad()
for most conversions between Wad
and Ray
.Into
trait only when a simple type cast is required (expected to be rare).The following functions are available for SignedWad
and SignedRay
via the Signed
trait:
is_negative()
: Returns true if the value is less than zerois_positive()
: Returns true if the value is greater than zeroTo use this library, add the repository as a dependency in your Scarb.toml
:
[dependencies]
wadray = "0.5.0"
then add the following line in your .cairo
file
use wadray::Wad;
fn add_wad(a: Wad, b: Wad) -> Wad {
a + b
}
You can also refer to the test file src/test_wadray.cairo
for another example.
To run the tests:
scarb test
This library has been formally verified using our tool Aegis. Specifications and their correctness proof can be found in this repository, the verification currently refers to revision 30f7664 of this repo.
We welcome contributions of any kind! Please feel free to submit an issue or open a PR if you have a solution to an existing bug.
This library is released under the MIT License.
Version 0.5.0
Uploaded 4 weeks ago
Size 12.2 KB
Run the following command in your project dir
scarb add wadray@0.5.0
Or add the following line to your Scarb.toml
wadray = "0.5.0"
Repository github.com/lindy-labs/wadray