Skip to content

Commit

Permalink
refactor uints
Browse files Browse the repository at this point in the history
  • Loading branch information
zielvna committed Apr 2, 2024
1 parent 4507feb commit 0c1cdd3
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 23 deletions.
44 changes: 21 additions & 23 deletions contracts/math/uints.ral
Original file line number Diff line number Diff line change
Expand Up @@ -103,54 +103,52 @@ Contract Uints () {
let bLower = low128(b)
let bHigher = high128(b)

let rLowerLower = aLower * bLower
let rHigherHigher = aHigher * bHigher
let rHigherLower = aHigher * bLower
let rLowerHigher = aLower * bHigher
let aLowerBLower = aLower * bLower
let aHigherBHigher = aHigher * bHigher
let aHigherBLower = aHigher * bLower
let aLowerBHigher = aLower * bHigher

let mut result = bigAdd512(U512 { higher: rHigherHigher, lower: rLowerLower }, U512 { higher: high128(rHigherLower), lower: low128(rHigherLower) << 128 })
result = bigAdd512(result, U512 { higher: high128(rLowerHigher), lower: low128(rLowerHigher) << 128 })
let mut result = bigAdd512(U512 { higher: aHigherBHigher, lower: aLowerBLower }, U512 { higher: high128(aHigherBLower), lower: low128(aHigherBLower) << 128 })
result = bigAdd512(result, U512 { higher: high128(aLowerBHigher), lower: low128(aLowerBHigher) << 128 })

result = bigDiv(result, denominator, 1)

return result
}

pub fn bigMulUp(a: U256, b: U256, denominator: U256) -> U512 {
let a0 = low128(a)
let a1 = high128(a)
let b0 = low128(b)
let b1 = high128(b)
let aLower = low128(a)
let aHigher = high128(a)
let bLower = low128(b)
let bHigher = high128(b)

let r0 = a0 * b0
let r1 = a1 * b1
let r2 = a1 * b0
let r3 = a0 * b1
let aLowerBLower = aLower * bLower
let aHigherBHigher = aHigher * bHigher
let aHigherBLower = aHigher * bLower
let aLowerBHigher = aLower * bHigher

let mut result = bigAdd512(U512 { higher: r1, lower: r0 }, U512 { higher: high128(r2), lower: low128(r2) << 128 })
result = bigAdd512(result, U512 { higher: high128(r3), lower: low128(r3) << 128 })
let mut result = bigAdd512(U512 { higher: aHigherBHigher, lower: aLowerBLower }, U512 { higher: high128(aHigherBLower), lower: low128(aHigherBLower) << 128 })
result = bigAdd512(result, U512 { higher: high128(aLowerBHigher), lower: low128(aLowerBHigher) << 128 })

result = bigAdd512(result, U512 { higher: 0, lower: 10 ** denominator - 1 })
result = bigAdd512(result, U512 { higher: 0, lower: denominator - 1 })
result = bigDiv(result, denominator, 1)

return result
}

pub fn overflowingAdd(a: U256, b: U256) -> (U256, U256) {
if (u256Max!() - a >= b) {
if (MaxU256 - a >= b) {
return a + b, 0
} else {
return b + (u256Max!() - a) - 1, 1
return b + (MaxU256 - a) - 1, 1
}
}

pub fn wrappingAdd(a: U256, b: U256) -> U256 {
let u256Max = u256Max!()

if (u256Max - a >= b) {
if (MaxU256 - a >= b) {
return a + b
} else {
return b + (u256Max - a) - 1
return b + (MaxU256 - a) - 1
}
}

Expand Down
67 changes: 67 additions & 0 deletions test/uints.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,73 @@ describe('uints tests', () => {
const result = (await uints.contractInstance.methods.bigMul({ args: { a, b, denominator: 1000n } })).returns
expect(result).toStrictEqual({ higher: 0n, lower: 2000n })
}
{
const a = 10n
const b = 37n
const result = (await uints.contractInstance.methods.bigMul({ args: { a, b, denominator: 100n } })).returns
expect(result).toStrictEqual({ higher: 0n, lower: 3n })
}
})

test('big mul up', async () => {
const uints = await deployUints(sender)
{
const a = 123n
const b = 2n
const result = (await uints.contractInstance.methods.bigMulUp({ args: { a, b, denominator: 1n } })).returns
expect(result).toStrictEqual({ higher: 0n, lower: 246n })
// expected: 246
// real: 246
}
{
const a = 340282366920938463463374607431768211457n
const b = 340282366920938463463374607431768211457n
const result = (await uints.contractInstance.methods.bigMulUp({ args: { a, b, denominator: 1n } })).returns
expect(result).toStrictEqual({ higher: 1n, lower: 680564733841876926926749214863536422913n })
// expected: 115792089237316195423570985008687907853950549399482440966384333222776666062849
// real: 115792089237316195423570985008687907853950549399482440966384333222776666062849
}
{
const a = 115792089237316195423570985008687907853269984665640564039457584007913129639935n
const b = 115792089237316195423570985008687907853269984665640564039457584007913129639935n
const result = (await uints.contractInstance.methods.bigMulUp({ args: { a, b, denominator: 1n } })).returns
expect(result).toStrictEqual({
higher: 115792089237316195423570985008687907853269984665640564039457584007913129639934n,
lower: 680564733841876926926749214863536422909n
})
// expected: 13407807929942597099574024998205846127479365820592393377723561443721764030073315392623399665776056285720014482370779510884422601683867654778417822746804225
// real: 13407807929942597099574024998205846127479365820592393377723561443721764030073315392623399665776056285720014482370780191449156443560794581527632686283227133
}
{
const a = 500n
const b = 0n
const result = (await uints.contractInstance.methods.bigMulUp({ args: { a, b, denominator: 1n } })).returns
expect(result).toStrictEqual({ higher: 0n, lower: 0n })
}
{
const a = 100n
const b = 100n
const result = (await uints.contractInstance.methods.bigMulUp({ args: { a, b, denominator: 100n } })).returns
expect(result).toStrictEqual({ higher: 0n, lower: 100n })
}
{
const a = 30n
const b = 1n
const result = (await uints.contractInstance.methods.bigMulUp({ args: { a, b, denominator: 10n } })).returns
expect(result).toStrictEqual({ higher: 0n, lower: 3n })
}
{
const a = 500n
const b = 4000n
const result = (await uints.contractInstance.methods.bigMulUp({ args: { a, b, denominator: 1000n } })).returns
expect(result).toStrictEqual({ higher: 0n, lower: 2000n })
}
{
const a = 10n
const b = 37n
const result = (await uints.contractInstance.methods.bigMulUp({ args: { a, b, denominator: 100n } })).returns
expect(result).toStrictEqual({ higher: 0n, lower: 4n })
}
})

test('overflowing add', async () => {
Expand Down

0 comments on commit 0c1cdd3

Please sign in to comment.