Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add mul 512 function and tests #43

Merged
merged 2 commits into from
Apr 4, 2024
Merged
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
100 changes: 55 additions & 45 deletions contracts/math/uints.ral
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
struct Result {
mut value: U512,
mut error: Bool
}

struct U512 {
mut higher: U256,
mut lower: U256
Expand All @@ -23,7 +28,7 @@ Contract Uints () {
return v.lower
}

pub fn bigAdd(a: U256, b: U256) -> U512 {
pub fn bigAdd256(a: U256, b: U256) -> U512 {
if (MaxU256 - a < b) {
return U512 {
higher: 1,
Expand All @@ -37,55 +42,60 @@ Contract Uints () {
}
}

pub fn div(a: U512, b: U256, bDenominator: U256, up: Bool) -> U512 {
assert!(b > 0, ArithmeticErrors.NotPositiveDivisor)
pub fn bigAdd512(a: U512, b: U512) -> U512 {
let (aLowerBLower, overflow) = overflowingAdd(a.lower, b.lower)
let aHigherBHigherOverflow = wrappingAdd(wrappingAdd(a.higher, b.higher), overflow)
return U512 { lower: aLowerBLower, higher: aHigherBHigherOverflow }
}

if (b == 1) {
return a
}
pub fn bigDivWrapper(a: U512, b: U256, bDenominator: U256, up: Bool) -> U512 {
assert!(b > 0, ArithmeticErrors.NotPositiveDivisor)

// Calculate new higher
let newHigher = a.higher * bDenominator
let higher = newHigher / b
let higherRemainder = newHigher % b
// calculate higher remainder
let maxDiv = MaxU256 / b
let deltaHigherRemainder = higherRemainder * maxDiv
// Calculate lower
let newLower = a.lower * bDenominator
let lower = newLower / b
let mut deltaLower = deltaHigherRemainder + lower

if (up) {
let lowerRemainder = newLower % b

let higherDecimal = deltaHigherRemainder % b
if (higherDecimal + lowerRemainder != 0) {
deltaLower = deltaLower + 1
}
}
if (b == 1) {
return a
}

return U512 {
higher: higher,
lower: deltaLower
// Calculate new higher
let newHigher = a.higher * bDenominator
let higher = newHigher / b
let higherRemainder = newHigher % b
// calculate higher remainder
let maxDiv = MaxU256 / b
let deltaHigherRemainder = higherRemainder * maxDiv
// Calculate lower
let newLower = a.lower * bDenominator
let lower = newLower / b
let mut deltaLower = deltaHigherRemainder + lower

if (up) {
let lowerRemainder = newLower % b

let higherDecimal = deltaHigherRemainder % b
if (higherDecimal + lowerRemainder != 0) {
deltaLower = deltaLower + 1
}
}

pub fn bigDiv(a: U512, b: U256, bDenominator: U256) -> U512 {
return div(a, b, bDenominator, false)
return U512 {
higher: higher,
lower: deltaLower
}
}

pub fn bigDivUp(a: U512, b: U256, bDenominator: U256) -> U512 {
return div(a, b, bDenominator, true)
}
pub fn bigDiv512(a: U512, b: U256, bDenominator: U256) -> U512 {
return bigDivWrapper(a, b, bDenominator, false)
}

pub fn bigAdd512(a: U512, b: U512) -> U512 {
let (aLowerBLower, overflow) = overflowingAdd(a.lower, b.lower)
let aHigherBHigherOverflow = wrappingAdd(wrappingAdd(a.higher, b.higher), overflow)
return U512 { lower: aLowerBLower, higher: aHigherBHigherOverflow }
pub fn bigDivUp512(a: U512, b: U256, bDenominator: U256) -> U512 {
return bigDivWrapper(a, b, bDenominator, true)
}

pub fn bigMul512(a: U512, b: U256) -> U512 {
let result = bigMul256(a.lower, b)
return bigAdd512(result, U512 { higher: a.higher * b, lower: 0 })
}

pub fn mul(a: U256, b: U256) -> U512 {
pub fn bigMul256(a: U256, b: U256) -> U512 {
let aLower = low128(a)
let aHigher = high128(a)
let bLower = low128(b)
Expand All @@ -106,19 +116,19 @@ Contract Uints () {
return U512 { higher: higher, lower: lower }
}

pub fn bigMul(a: U256, b: U256, bDenominator: U256) -> U512 {
let mut result = mul(a, b)
pub fn bigMulDiv256(a: U256, b: U256, bDenominator: U256) -> U512 {
let mut result = bigMul256(a, b)

result = bigDiv(result, bDenominator, 1)
result = bigDiv512(result, bDenominator, 1)

return result
}

pub fn bigMulUp(a: U256, b: U256, bDenominator: U256) -> U512 {
let mut result = mul(a, b)
pub fn bigMulDivUp256(a: U256, b: U256, bDenominator: U256) -> U512 {
let mut result = bigMul256(a, b)

result = bigAdd512(result, U512 { higher: 0, lower: bDenominator - 1 })
result = bigDiv(result, bDenominator, 1)
result = bigDiv512(result, bDenominator, 1)

return result
}
Expand Down
Loading
Loading