Code Monkey home page Code Monkey logo

wadray's Introduction

WadRay library for Cairo

tests

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

Overview

This library includes arithmetic, comparison and conversion functions.

Arithmetic

Addition and Subtraction

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

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 values

The following values and functions for both Wad and Ray, and SignedWad and SignedRay, are available via the Zeroable and Oneable traits.

Unsigned
  • WadZeroable::zero()/RayZeroable::zero(): Returns the zero value for Wad and Ray respectively
  • is_zero(): Returns true if the Wad or Ray value is zero
  • is_non_zero() Returns true if the Wad or Ray value is not zero
  • WadOneable::one()/RayOneable::one(): Returns the scale value for Wad (i.e. 1018) and Ray (i.e. 1027) respectively
  • is_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)
Signed
  • SignedWadZeroable::zero()/SignedRayZeroable::zero(): Returns the zero value for Wad and Ray respectively
  • is_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 zero
  • SignedWadOneable::one()/SignedRayOneable::one(): Returns the positive scale value for "wad" (i.e. 1018) and "ray" (i.e. 1027) respectively
  • is_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)

Bound values

The bound values for both Wad and Ray can be obtained via the BoundedInt trait.

  • BoundedWad::max(): Returns the maximum Wad value of 2128 - 1
  • BoundedWad::min(): Returns the minimum Wad value of 0
  • BoundedRay::max(): Returns the maximum Ray value of 2128 - 1
  • BoundedRay::min(): Returns the minimum Ray value of 0

Comparisons

Comparison 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.

Conversion

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 value
  • Wad -> u256: Convert a Wad to a u256 without modifying the value
  • Wad -> SignedWad: Convert a Wad to a SignedWad without modifying the value, with the sign set to false
  • Wad -> SignedRay: Multiply the Wad by 109 and return a SignedRay with the sign set to false
  • Ray -> Wad: Divide the Ray value by 109 and return a Wad
  • 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 value
  • SignedRay -> felt252: Convert a SignedRay to a felt252 without modifying the value

The following conversions can be performed via the TryInto trait:

  • Wad -> Option::<Ray>: Multiply the Wad value by 109 and return Option::Some<Ray> if there is no overflow or Option::None otherwise
  • u256 -> Option::<Wad>: Returns Option::Some<Wad> if the value is within bounds of u128 or Option::None otherwise
  • SignedWad -> Option::<Wad>: Returns Option::Some<Wad> if sign is false or Option::None otherwise
  • SignedRay -> Option::<Ray>: Returns Option::Some<Ray> if sign is false or Option::None otherwise

Signed

The following functions are available for SignedWad and SignedRay via the Signed trait:

  • is_negative(): Returns true if the value is less than zero
  • is_positive(): Returns true if the value is greater than zero

Usage

To use this library, add the repository as a dependency in your Scarb.toml:

[dependencies]
wadray = { git = "https://github.com/lindy-labs/wadray.git" }

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.

Development

Prerequisites

Run tests

To run the tests:

scarb test

Formal Verification

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.

Contribute

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.

License

This library is released under the MIT License.

wadray's People

Contributors

tserg avatar milancermak avatar javra avatar bllu404 avatar 0xbrm avatar

Stargazers

 avatar  avatar krpnt avatar sudo rm -rf --no-preserve-root / avatar A₿del ∞/21M 🐺 - 🐱 avatar Roberto J Catalan avatar Ondřej Sojka avatar Mehdi-DeFiesta avatar 0xevolve avatar whatthedev.eth avatar nael avatar  avatar Etch avatar Jason Zhou avatar StarkNet 中文 | China avatar massil avatar BigSky avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

tserg enitrat tadev0

wadray's Issues

Release v0.1

After #13 and #14 are resolved, we should do a first release. It should be available for Cairo 2.3.1 and will enable us to move adopting some 2.4.0 features (e.g. Debug trait) into the next release.

Implement BoundedInt for Signed types

SignedWad and SignedRay are missing BoundedInt impls, which Wad and Ray has.

As a general rule to follow, IMO both signed and unsigned types should implement the same traits where it makes sense.

Simplify imports

Importing from the lib is unnecessarily verbose. use wadray::wadray::Wad should be just use wadray::Wad.

For signed types, we both use wadray::SignedWad and wadray::signed::SignedWad make sense to me, but I have a slight preference for the first choice. Curious to read your thoughts.

At the same time, we should rename the repo to just wadray so the dependency definition would become cleaner, more consistent -> wadray = { git = "https://github.com/lindy-labs/wadray.git" }.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.