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
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 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) UInt64(sum)
} }
def - (num : UnsignedNumber) = num match { def - (num : UnsignedNumber): UnsignedNumber = {
case uInt32 : UInt32 => val result = num match {
val result = underlying - uInt32.underlying case uInt32 : UInt32 =>underlying - uInt32.underlying
case uInt64 : UInt64 => underlying - uInt64.underlying
}
if (result < 0) throw new RuntimeException("Cannot have a negative unsigned number, " + 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) else UInt64(result)
case uInt64 : UInt64 => }
val result = underlying - uInt64.underlying
if (result < 0) throw new RuntimeException("Cannot have a negative unsigned number, " + override def * (num : UnsignedNumber): UnsignedNumber = {
"got one subtracting: " + underlying + " and " + uInt64.underlying) 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) 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 = ??? 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 { 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 => property("additive identity") = Prop.forAll(NumberGenerator.uInt32s) { num : UInt32 =>
num + UInt32.zero == num 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") = property("Serialization symmetry") =
Prop.forAll(NumberGenerator.uInt64s) { uInt64 : UInt64 => Prop.forAll(NumberGenerator.uInt64s) { uInt64 : UInt64 =>
UInt64(uInt64.hex) == uInt64 UInt64(uInt64.hex) == uInt64
UInt64(uInt64.hex).hex == uInt64.hex
} }
property("additive identity") = property("additive identity") =
@ -34,7 +35,6 @@ class UInt64Specification extends Properties("UInt64Spec") with BitcoinSLogger {
else Try(num1 + num2).isFailure else Try(num1 + num2).isFailure
} }
property("subtractive identity") = property("subtractive identity") =
Prop.forAll(NumberGenerator.uInt64s) { uInt64 : UInt64 => Prop.forAll(NumberGenerator.uInt64s) { uInt64 : UInt64 =>
uInt64 - UInt64.zero == uInt64 uInt64 - UInt64.zero == uInt64
@ -54,4 +54,29 @@ class UInt64Specification extends Properties("UInt64Spec") with BitcoinSLogger {
if (result >= 0) num1 - num2 == UInt64(result) if (result >= 0) num1 - num2 == UInt64(result)
else Try(num1 - num2).isFailure 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
}
} }