mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-01-19 05:43:51 +01:00
Adding BaseNumbers trait, start to implement addition
This commit is contained in:
parent
c7dc6dca77
commit
50a59aef2c
@ -1,11 +1,12 @@
|
|||||||
package org.bitcoins.core.number
|
package org.bitcoins.core.number
|
||||||
|
|
||||||
import org.bitcoins.core.util.{BitcoinSLogger, Factory, NumberUtil}
|
import org.bitcoins.core.protocol.NetworkElement
|
||||||
|
import org.bitcoins.core.util.{BitcoinSLogger, BitcoinSUtil, Factory, NumberUtil}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by chris on 6/4/16.
|
* Created by chris on 6/4/16.
|
||||||
*/
|
*/
|
||||||
sealed trait Number extends BitcoinSLogger {
|
sealed trait Number extends NetworkElement with BitcoinSLogger {
|
||||||
type A
|
type A
|
||||||
def underlying : A
|
def underlying : A
|
||||||
def + (num : Number): Number
|
def + (num : Number): Number
|
||||||
@ -21,7 +22,10 @@ sealed trait UInt32 extends UnsignedNumber {
|
|||||||
override type A = Long
|
override type A = Long
|
||||||
|
|
||||||
def + (num : Number): Number = num match {
|
def + (num : Number): Number = num match {
|
||||||
case uInt32 : UInt32 => UInt64(underlying + uInt32.underlying)
|
case uInt32 : UInt32 =>
|
||||||
|
val n : BigInt = underlying + uInt32.underlying
|
||||||
|
if (n == n.toLong) UInt32(n.toLong)
|
||||||
|
else UInt64(n)
|
||||||
case uInt64 : UInt64 => UInt64(uInt64.underlying + underlying)
|
case uInt64 : UInt64 => UInt64(uInt64.underlying + underlying)
|
||||||
case int32 : Int32 => ???
|
case int32 : Int32 => ???
|
||||||
case int64 : Int64 => ???
|
case int64 : Int64 => ???
|
||||||
@ -60,16 +64,19 @@ object UnsignedNumber extends Factory[UnsignedNumber] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
trait BaseNumbers {
|
* Represents various numbers that should be implemented
|
||||||
def zero : Number
|
* inside of any companion object for a [[Number]]
|
||||||
def one : Number
|
*/
|
||||||
def min : Number
|
trait BaseNumbers[T <: Number] {
|
||||||
def max : Number
|
def zero : T
|
||||||
|
def one : T
|
||||||
|
def min : T
|
||||||
|
def max : T
|
||||||
}
|
}
|
||||||
|
|
||||||
object UInt32 extends Factory[UInt32] with BitcoinSLogger with BaseNumbers {
|
object UInt32 extends Factory[UInt32] with BitcoinSLogger with BaseNumbers[UInt32] {
|
||||||
private case class UInt32Impl(underlying : Long) extends UInt32
|
private case class UInt32Impl(underlying : Long, hex : String) extends UInt32
|
||||||
|
|
||||||
lazy val zero = fromBytes(Seq(0.toByte))
|
lazy val zero = fromBytes(Seq(0.toByte))
|
||||||
lazy val one = fromBytes(Seq(1.toByte))
|
lazy val one = fromBytes(Seq(1.toByte))
|
||||||
@ -82,18 +89,20 @@ object UInt32 extends Factory[UInt32] with BitcoinSLogger with BaseNumbers {
|
|||||||
val individualByteValues = for {
|
val individualByteValues = for {
|
||||||
(byte,index) <- bytes.reverse.zipWithIndex
|
(byte,index) <- bytes.reverse.zipWithIndex
|
||||||
} yield NumberUtil.calculateNumberFromByte(index, byte)
|
} yield NumberUtil.calculateNumberFromByte(index, byte)
|
||||||
UInt32Impl(individualByteValues.sum.toLong)
|
UInt32Impl(individualByteValues.sum.toLong, BitcoinSUtil.encodeHex(bytes))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def apply(long : Long) : UInt32 = UInt32Impl(long, BitcoinSUtil.encodeHex(BigInt(long).toByteArray))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
object UInt64 extends Factory[UInt64] with BitcoinSLogger with BaseNumbers {
|
object UInt64 extends Factory[UInt64] with BitcoinSLogger with BaseNumbers[UInt64] {
|
||||||
private case class UInt64Impl(underlying : BigInt) extends UInt64
|
private case class UInt64Impl(underlying : BigInt, hex : String) extends UInt64
|
||||||
|
|
||||||
lazy val zero = UInt32.zero
|
lazy val zero = fromBytes(Seq(0.toByte))
|
||||||
lazy val one = UInt32.one
|
lazy val one = fromBytes(Seq(1.toByte))
|
||||||
|
|
||||||
lazy val min = zero
|
lazy val min = zero
|
||||||
lazy val max = fromBytes(Seq(0xff.toByte, 0xff.toByte, 0xff.toByte, 0xff.toByte,
|
lazy val max = fromBytes(Seq(0xff.toByte, 0xff.toByte, 0xff.toByte, 0xff.toByte,
|
||||||
@ -105,15 +114,15 @@ object UInt64 extends Factory[UInt64] with BitcoinSLogger with BaseNumbers {
|
|||||||
(byte,index) <- bytes.reverse.zipWithIndex
|
(byte,index) <- bytes.reverse.zipWithIndex
|
||||||
} yield NumberUtil.calculateNumberFromByte(index, byte)
|
} yield NumberUtil.calculateNumberFromByte(index, byte)
|
||||||
logger.debug("Individual bytes values: " + individualByteValues)
|
logger.debug("Individual bytes values: " + individualByteValues)
|
||||||
UInt64Impl(individualByteValues.sum)
|
UInt64Impl(individualByteValues.sum, BitcoinSUtil.encodeHex(bytes))
|
||||||
}
|
}
|
||||||
|
|
||||||
def apply(num : BigInt): UInt64 = UInt64Impl(num)
|
def apply(num : BigInt): UInt64 = UInt64Impl(num, BitcoinSUtil.encodeHex(num.toByteArray))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
object Int32 extends Factory[Int32] with BaseNumbers {
|
object Int32 extends Factory[Int32] with BaseNumbers[Int32] {
|
||||||
private case class Int32Impl(underlying : Int) extends Int32
|
private case class Int32Impl(underlying : Int, hex : String) extends Int32
|
||||||
|
|
||||||
lazy val zero = fromBytes(Seq(0.toByte))
|
lazy val zero = fromBytes(Seq(0.toByte))
|
||||||
lazy val one = fromBytes(Seq(1.toByte))
|
lazy val one = fromBytes(Seq(1.toByte))
|
||||||
@ -123,22 +132,22 @@ object Int32 extends Factory[Int32] with BaseNumbers {
|
|||||||
|
|
||||||
override def fromBytes(bytes : Seq[Byte]): Int32 = {
|
override def fromBytes(bytes : Seq[Byte]): Int32 = {
|
||||||
require(bytes.size <= 4, "We cannot have an Int32 be larger than 4 bytes")
|
require(bytes.size <= 4, "We cannot have an Int32 be larger than 4 bytes")
|
||||||
Int32Impl(BigInt(bytes.toArray).toInt)
|
Int32Impl(BigInt(bytes.toArray).toInt, BitcoinSUtil.encodeHex(bytes))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
object Int64 extends Factory[Int64] with BaseNumbers {
|
object Int64 extends Factory[Int64] with BaseNumbers[Int64] {
|
||||||
private case class Int64Impl(underlying : Long) extends Int64
|
private case class Int64Impl(underlying : Long, hex : String) extends Int64
|
||||||
|
|
||||||
lazy val zero = Int32.zero
|
lazy val zero = fromBytes(Seq(0.toByte))
|
||||||
lazy val one = Int32.one
|
lazy val one = fromBytes(Seq(1.toByte))
|
||||||
|
|
||||||
lazy val min = fromBytes(Seq(0x80.toByte,0.toByte, 0.toByte, 0.toByte,0.toByte, 0.toByte, 0.toByte, 0.toByte))
|
lazy val min = fromBytes(Seq(0x80.toByte,0.toByte, 0.toByte, 0.toByte,0.toByte, 0.toByte, 0.toByte, 0.toByte))
|
||||||
lazy val max = fromBytes(Seq(0x7f.toByte, 0xff.toByte, 0xff.toByte, 0xff.toByte,
|
lazy val max = fromBytes(Seq(0x7f.toByte, 0xff.toByte, 0xff.toByte, 0xff.toByte,
|
||||||
0xff.toByte, 0xff.toByte, 0xff.toByte, 0xff.toByte))
|
0xff.toByte, 0xff.toByte, 0xff.toByte, 0xff.toByte))
|
||||||
override def fromBytes(bytes : Seq[Byte]): Int64 = {
|
override def fromBytes(bytes : Seq[Byte]): Int64 = {
|
||||||
require(bytes.size <= 8, "We cannot have an Int64 be larger than 8 bytes")
|
require(bytes.size <= 8, "We cannot have an Int64 be larger than 8 bytes")
|
||||||
Int64Impl(BigInt(bytes.toArray).toLong)
|
Int64Impl(BigInt(bytes.toArray).toLong, BitcoinSUtil.encodeHex(bytes))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,4 +70,11 @@ class UInt32Test extends FlatSpec with MustMatchers {
|
|||||||
it must "have the correct maximum number representation for UInt32" in {
|
it must "have the correct maximum number representation for UInt32" in {
|
||||||
UInt32.max.underlying must be (4294967295L)
|
UInt32.max.underlying must be (4294967295L)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//addition tests
|
||||||
|
|
||||||
|
it must "say 0 + 0 = 0" in {
|
||||||
|
(UInt32.zero + UInt32.zero) must be (UInt32.zero)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user