Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ on:
- main

jobs:
main:
test-w-cairo-2-8-4:
name: Test with Cairo 2.8.4
runs-on: ubuntu-latest
steps:
- name: Checkout
Expand All @@ -18,7 +19,23 @@ jobs:
- name: Setup Cairo toolchain
uses: software-mansion/setup-scarb@v1
with:
scarb-version: "2.4.0"
scarb-version: "2.8.4"

- name: Run tests
run: scarb test

test-w-cairo-2-9-2:
name: Test with Cairo 2.9.2
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Setup Cairo toolchain
uses: software-mansion/setup-scarb@v1
with:
scarb-version: "2.9.2"

- name: Run tests
run: scarb test

6 changes: 5 additions & 1 deletion Scarb.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "cubit"
version = "1.3.0"
cairo-version = ">=2.4.0"
cairo-version = ">=2.8.0"
edition = "2023_10"
description = "Math library in Cairo using a 64.64 fixed point representation"
homepage = "https://github.com/influenceth/cubit"
Expand All @@ -11,3 +11,7 @@ sierra = false # Enable Sierra codegen.
casm = false # Enable CASM codegen.

[dependencies]
starknet = ">=2.8.0"

[dev-dependencies]
cairo_test = "2.8.4"
81 changes: 38 additions & 43 deletions src/f128/math/ops.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ use core::option::OptionTrait;
use core::result::{ResultTrait, ResultTraitImpl};
use core::traits::{Into, TryInto};
use core::integer;
use core::integer::{u256_safe_div_rem, u256_as_non_zero, upcast};
use core::num::traits::{WideMul, Sqrt};
use core::integer::{u256_safe_div_rem, u256_as_non_zero};

use cubit::f128::math::lut;
use cubit::f128::types::fixed::{
HALF_u128, MAX_u128, ONE_u128, Fixed, FixedInto, FixedTrait, FixedAdd, FixedDiv, FixedMul,
FixedNeg
HALF_u128, MAX_u128, ONE_u128, ONE_u256, SQRT_ONE_u128, Fixed, FixedInto, FixedTrait, FixedAdd,
FixedDiv, FixedMul, FixedNeg
};

// PUBLIC
Expand Down Expand Up @@ -48,9 +49,8 @@ fn ceil(a: Fixed) -> Fixed {
}

fn div(a: Fixed, b: Fixed) -> Fixed {
let (a_high, a_low) = integer::u128_wide_mul(a.mag, ONE_u128);
let a_u256 = u256 { low: a_low, high: a_high };
let b_u256 = u256 { low: b.mag, high: 0 };
let a_u256 = a.mag.wide_mul(ONE_u128);
let b_u256 = b.mag.into();
let res_u256 = a_u256 / b_u256;

assert(res_u256.high == 0, 'result overflow');
Expand Down Expand Up @@ -91,7 +91,7 @@ fn exp2(a: Fixed) -> Fixed {
res_u = res_u * (r1 + FixedTrait::ONE());
}

if (a.sign == true) {
if (a.sign) {
return FixedTrait::ONE() / res_u;
} else {
return res_u;
Expand Down Expand Up @@ -147,7 +147,7 @@ fn ln(a: Fixed) -> Fixed {
// Calculates the binary logarithm of x: log2(x)
// self must be greather than zero
fn log2(a: Fixed) -> Fixed {
assert(a.sign == false, 'must be positive');
assert(!a.sign, 'must be positive');

if (a.mag == ONE_u128) {
return FixedTrait::ZERO();
Expand Down Expand Up @@ -186,9 +186,7 @@ fn lt(a: Fixed, b: Fixed) -> bool {
}

fn mul(a: Fixed, b: Fixed) -> Fixed {
let (high, low) = integer::u128_wide_mul(a.mag, b.mag);
let res_u256 = u256 { low: low, high: high };
let ONE_u256 = u256 { low: ONE_u128, high: 0 };
let res_u256 = a.mag.wide_mul(b.mag);
let (scaled_u256, _) = u256_safe_div_rem(res_u256, u256_as_non_zero(ONE_u256));

assert(scaled_u256.high == 0, 'result overflow');
Expand All @@ -204,8 +202,8 @@ struct f64 {
}

fn mul_64(a: f64, b: f64) -> f64 {
let prod_u128 = integer::u64_wide_mul(a.mag, b.mag);
return f64 { mag: (prod_u128 / 4294967296).try_into().unwrap(), sign: a.sign ^ b.sign };
let prod_u128 = a.mag.wide_mul(b.mag);
return f64 { mag: (prod_u128 / SQRT_ONE_u128).try_into().unwrap(), sign: a.sign ^ b.sign };
}

fn ne(a: @Fixed, b: @Fixed) -> bool {
Expand Down Expand Up @@ -242,7 +240,7 @@ fn pow_int(a: Fixed, b: u128, sign: bool) -> Fixed {
let mut x = a;
let mut n = b;

if sign == true {
if sign {
x = FixedTrait::ONE() / x;
}

Expand Down Expand Up @@ -288,10 +286,8 @@ fn round(a: Fixed) -> Fixed {
// Calculates the square root of a fixed point value
// x must be positive
fn sqrt(a: Fixed) -> Fixed {
assert(a.sign == false, 'must be positive');
let root = integer::u128_sqrt(a.mag);
let scale_root = integer::u128_sqrt(ONE_u128);
let res_u128 = upcast(root) * ONE_u128 / upcast(scale_root);
assert(!a.sign, 'must be positive');
let res_u128 = a.mag.sqrt().into() * ONE_u128 / SQRT_ONE_u128;
return FixedTrait::new(res_u128, false);
}

Expand All @@ -304,19 +300,18 @@ fn _split_unsigned(a: Fixed) -> (u128, u128) {
return integer::u128_safe_divmod(a.mag, integer::u128_as_non_zero(ONE_u128));
}

// Tests --------------------------------------------------------------------------------------------------------------
// Tests
// --------------------------------------------------------------------------------------------------------------

#[cfg(test)]
mod tests {
use cubit::f128::test::helpers::assert_precise;
use cubit::f128::types::fixed::{
ONE, HALF, FixedPartialEq, FixedPartialOrd, FixedAddEq, FixedSub, FixedSubEq, FixedMulEq
};
use cubit::f128::types::fixed::{ONE, HALF};

use cubit::f128::math::trig::HALF_PI_u128;
use cubit::f128::math::trig::PI_u128;

use super::{FixedTrait, ONE_u128, lut, exp2_int, integer};
use super::{FixedTrait, ONE_u128, lut, exp2_int};

#[test]
fn test_into() {
Expand Down Expand Up @@ -495,15 +490,15 @@ mod tests {
let a = FixedTrait::from_unscaled_felt(42);
let b = FixedTrait::from_unscaled_felt(42);
let c = a == b;
assert(c == true, 'invalid result');
assert(c, 'invalid result');
}

#[test]
fn test_ne() {
let a = FixedTrait::from_unscaled_felt(42);
let b = FixedTrait::from_unscaled_felt(42);
let c = a != b;
assert(c == false, 'invalid result');
assert(!c, 'invalid result');
}

#[test]
Expand Down Expand Up @@ -577,12 +572,12 @@ mod tests {
let c = FixedTrait::from_unscaled_felt(-1);

assert(a <= a, 'a <= a');
assert(a <= b == false, 'a <= b');
assert(a <= c == false, 'a <= c');
assert(!(a <= b), 'a <= b');
assert(!(a <= c), 'a <= c');

assert(b <= a, 'b <= a');
assert(b <= b, 'b <= b');
assert(b <= c == false, 'b <= c');
assert(!(b <= c), 'b <= c');

assert(c <= a, 'c <= a');
assert(c <= b, 'c <= b');
Expand All @@ -595,17 +590,17 @@ mod tests {
let b = FixedTrait::from_unscaled_felt(0);
let c = FixedTrait::from_unscaled_felt(-1);

assert(a < a == false, 'a < a');
assert(a < b == false, 'a < b');
assert(a < c == false, 'a < c');
assert(!(a < a), 'a < a');
assert(!(a < b), 'a < b');
assert(!(a < c), 'a < c');

assert(b < a, 'b < a');
assert(b < b == false, 'b < b');
assert(b < c == false, 'b < c');
assert(!(b < b), 'b < b');
assert(!(b < c), 'b < c');

assert(c < a, 'c < a');
assert(c < b, 'c < b');
assert(c < c == false, 'c < c');
assert(!(c < c), 'c < c');
}

#[test]
Expand All @@ -618,12 +613,12 @@ mod tests {
assert(a >= b, 'a >= b');
assert(a >= c, 'a >= c');

assert(b >= a == false, 'b >= a');
assert(!(b >= a), 'b >= a');
assert(b >= b, 'b >= b');
assert(b >= c, 'b >= c');

assert(c >= a == false, 'c >= a');
assert(c >= b == false, 'c >= b');
assert(!(c >= a), 'c >= a');
assert(!(c >= b), 'c >= b');
assert(c >= c, 'c >= c');
}

Expand All @@ -633,17 +628,17 @@ mod tests {
let b = FixedTrait::from_unscaled_felt(0);
let c = FixedTrait::from_unscaled_felt(-1);

assert(a > a == false, 'a > a');
assert(!(a > a), 'a > a');
assert(a > b, 'a > b');
assert(a > c, 'a > c');

assert(b > a == false, 'b > a');
assert(b > b == false, 'b > b');
assert(!(b > a), 'b > a');
assert(!(b > b), 'b > b');
assert(b > c, 'b > c');

assert(c > a == false, 'c > a');
assert(c > b == false, 'c > b');
assert(c > c == false, 'c > c');
assert(!(c > a), 'c > a');
assert(!(c > b), 'c > b');
assert(!(c > c), 'c > c');
}

#[test]
Expand Down
Loading