Adding multiplicative properties for UInt64

This commit is contained in:
Chris Stewart 2016-06-20 18:58:12 -05:00
parent 43dacf7354
commit 17e7bb67c3
3 changed files with 54 additions and 27 deletions

View file

@ -66,7 +66,6 @@ sealed trait NumberOperations[T <: Number] {
def >= (num : T): Boolean
def < (num : T): Boolean
def <= (num : T): Boolean
def == (num : T): Boolean
}
@ -128,10 +127,6 @@ sealed trait UInt32 extends UnsignedNumber with NumberOperations[UnsignedNumber]
case uInt64 : UInt64 => underlying <= uInt64.underlying
}
def == (num : UnsignedNumber): Boolean = num match {
case uInt32 : UInt32 => underlying == uInt32.underlying
case uInt64 : UInt64 => underlying == uInt64.underlying
}
}
/**
@ -148,16 +143,23 @@ sealed trait UInt64 extends UnsignedNumber with NumberOperations[UnsignedNumber]
UInt64(sum)
}
def - (num : UnsignedNumber) = num match {
case uInt32 : UInt32 =>
val result = underlying - uInt32.underlying
def - (num : UnsignedNumber): UnsignedNumber = {
val result = num match {
case uInt32 : UInt32 =>underlying - uInt32.underlying
case uInt64 : UInt64 => underlying - uInt64.underlying
}
if (result < 0) throw new RuntimeException("Cannot have a negative unsigned number, " +
"got one subtracting: " + underlying + " and " + uInt32.underlying)
"got one subtracting: " + this + " and " + num)
else UInt64(result)
case uInt64 : UInt64 =>
val result = underlying - uInt64.underlying
if (result < 0) throw new RuntimeException("Cannot have a negative unsigned number, " +
"got one subtracting: " + underlying + " and " + uInt64.underlying)
}
override def * (num : UnsignedNumber): UnsignedNumber = {
val result = num match {
case uInt32 : UInt32 => underlying * uInt32.underlying
case uInt64 : UInt64 => underlying * uInt64.underlying
}
if (result > UInt64.max.underlying) throw new RuntimeException("The product of " + this +
" and " + num + " was too large for UInt64")
else UInt64(result)
}
@ -168,10 +170,7 @@ sealed trait UInt64 extends UnsignedNumber with NumberOperations[UnsignedNumber]
}
def < (num : UnsignedNumber): Boolean = ???
def <= (num : UnsignedNumber): Boolean = ???
def == (num : UnsignedNumber): Boolean = num match {
case uInt32 : UInt32 => num.underlying == uInt32.underlying
case uInt64 : UInt64 => num.underlying == uInt64.underlying
}
}
/**

View file

@ -10,6 +10,14 @@ import scala.util.Try
*/
class UInt32Specification extends Properties("UInt32") with BitcoinSLogger {
property("serialization symmetry") = {
Prop.forAll(NumberGenerator.uInt32s) { uInt32 : UInt32 =>
UInt32(uInt32.hex) == uInt32
UInt32(uInt32.hex).hex == uInt32.hex
}
}
property("additive identity") = Prop.forAll(NumberGenerator.uInt32s) { num : UInt32 =>
num + UInt32.zero == num
}
@ -102,11 +110,6 @@ class UInt32Specification extends Properties("UInt32") with BitcoinSLogger {
}
}
property("serialization symmetry") = {
Prop.forAll(NumberGenerator.uInt32s) { uInt32 : UInt32 =>
UInt32(uInt32.hex) == uInt32
UInt32(uInt32.hex).hex == uInt32.hex
}
}
}

View file

@ -14,6 +14,7 @@ class UInt64Specification extends Properties("UInt64Spec") with BitcoinSLogger {
property("Serialization symmetry") =
Prop.forAll(NumberGenerator.uInt64s) { uInt64 : UInt64 =>
UInt64(uInt64.hex) == uInt64
UInt64(uInt64.hex).hex == uInt64.hex
}
property("additive identity") =
@ -34,7 +35,6 @@ class UInt64Specification extends Properties("UInt64Spec") with BitcoinSLogger {
else Try(num1 + num2).isFailure
}
property("subtractive identity") =
Prop.forAll(NumberGenerator.uInt64s) { uInt64 : UInt64 =>
uInt64 - UInt64.zero == uInt64
@ -54,4 +54,29 @@ class UInt64Specification extends Properties("UInt64Spec") with BitcoinSLogger {
if (result >= 0) num1 - num2 == UInt64(result)
else Try(num1 - num2).isFailure
}
property("multiplying by zero") =
Prop.forAll(NumberGenerator.uInt64s) { uInt64 : UInt64 =>
uInt64 * UInt64.zero == UInt64.zero
}
property("multiplicative identity") =
Prop.forAll(NumberGenerator.uInt64s) { uInt64 : UInt64 =>
if (uInt64 == UInt64.zero) uInt64 * UInt64.one == UInt64.zero
else uInt64 * UInt64.one == uInt64
}
property("multiply uInt64 and a uInt32") =
Prop.forAll(NumberGenerator.uInt64s, NumberGenerator.uInt32s) { (uInt64 : UInt64, uInt32 : UInt32) =>
val result = uInt64.underlying * uInt32.underlying
if (result <= UInt64.max.underlying) uInt64 * uInt32 == UInt64(result)
else Try(uInt64 * uInt32).isFailure
}
property("multiply two uInt64s") =
Prop.forAll(NumberGenerator.uInt64s, NumberGenerator.uInt64s) { (num1 : UInt64, num2 : UInt64) =>
val result = num1.underlying * num2.underlying
if (result <= UInt64.max.underlying) num1 * num2 == UInt64(result)
else Try(num1 * num2).isFailure
}
}