mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-02-24 15:02:17 +01:00
Adding 'Bitconis' Currency unit type, adding unary '-' operator to negate the underlying values of CurrencyUnits / Int32s / Int64s
This commit is contained in:
parent
2ca4627ca7
commit
1bf3558cf5
4 changed files with 70 additions and 17 deletions
|
@ -1,5 +1,6 @@
|
|||
package org.bitcoins.core.currency
|
||||
|
||||
import org.bitcoins.core.consensus.Consensus
|
||||
import org.bitcoins.core.number.{BaseNumbers, Int32, Int64, SignedNumber}
|
||||
import org.bitcoins.core.protocol.NetworkElement
|
||||
import org.bitcoins.core.serializers.{RawBitcoinSerializerHelper, RawSatoshisSerializer}
|
||||
|
@ -10,41 +11,48 @@ sealed trait CurrencyUnit extends NetworkElement with BitcoinSLogger {
|
|||
type A
|
||||
def underlying : A
|
||||
|
||||
def satoshis: Satoshis
|
||||
|
||||
def >=(c : CurrencyUnit) : Boolean = {
|
||||
CurrencyUnits.toSatoshis(this).underlying >= CurrencyUnits.toSatoshis(c).underlying
|
||||
satoshis.underlying >= c.satoshis.underlying
|
||||
}
|
||||
|
||||
def >(c : CurrencyUnit) : Boolean = {
|
||||
CurrencyUnits.toSatoshis(this).underlying > CurrencyUnits.toSatoshis(c).underlying
|
||||
satoshis.underlying > c.satoshis.underlying
|
||||
}
|
||||
|
||||
def <(c : CurrencyUnit) : Boolean = {
|
||||
CurrencyUnits.toSatoshis(this).underlying < CurrencyUnits.toSatoshis(c).underlying
|
||||
satoshis.underlying < c.satoshis.underlying
|
||||
}
|
||||
|
||||
def <=(c : CurrencyUnit) : Boolean = {
|
||||
CurrencyUnits.toSatoshis(this).underlying <= CurrencyUnits.toSatoshis(c).underlying
|
||||
satoshis.underlying <= c.satoshis.underlying
|
||||
}
|
||||
|
||||
def !=(c : CurrencyUnit) : Boolean = !(this == c)
|
||||
|
||||
|
||||
def +(c : CurrencyUnit) : CurrencyUnit = {
|
||||
Satoshis(CurrencyUnits.toSatoshis(this).underlying + CurrencyUnits.toSatoshis(c).underlying)
|
||||
Satoshis(satoshis.underlying + c.satoshis.underlying)
|
||||
}
|
||||
|
||||
def -(c : CurrencyUnit) : CurrencyUnit = {
|
||||
Satoshis(CurrencyUnits.toSatoshis(this).underlying - CurrencyUnits.toSatoshis(c).underlying)
|
||||
Satoshis(satoshis.underlying - c.satoshis.underlying)
|
||||
}
|
||||
|
||||
def *(c : CurrencyUnit) : CurrencyUnit = {
|
||||
Satoshis(CurrencyUnits.toSatoshis(this).underlying * CurrencyUnits.toSatoshis(c).underlying)
|
||||
Satoshis(satoshis.underlying * c.satoshis.underlying)
|
||||
}
|
||||
|
||||
def unary_- : CurrencyUnit = {
|
||||
Satoshis(- satoshis.underlying)
|
||||
}
|
||||
}
|
||||
|
||||
sealed trait Satoshis extends CurrencyUnit {
|
||||
override type A = Int64
|
||||
override def hex = RawSatoshisSerializer.write(this)
|
||||
override def satoshis: Satoshis = this
|
||||
}
|
||||
|
||||
object Satoshis extends Factory[Satoshis] with BaseNumbers[Satoshis] {
|
||||
|
@ -60,14 +68,41 @@ object Satoshis extends Factory[Satoshis] with BaseNumbers[Satoshis] {
|
|||
def apply(int64: Int64): Satoshis = SatoshisImpl(int64)
|
||||
}
|
||||
|
||||
object CurrencyUnits {
|
||||
def zero : CurrencyUnit = Satoshis.zero
|
||||
def negativeSatoshi = Satoshis(Int64(-1))
|
||||
/** The number you need to multiply BTC by to get it's satoshis */
|
||||
def btcToSatoshiScalar = 100000000
|
||||
sealed trait Bitcoins extends CurrencyUnit {
|
||||
override type A = BigDecimal
|
||||
override def satoshis: Satoshis = {
|
||||
val sat = underlying * CurrencyUnits.btcToSatoshiScalar
|
||||
Satoshis(Int64(sat.toLongExact))
|
||||
}
|
||||
override def hex = satoshis.hex
|
||||
}
|
||||
|
||||
def oneBTC: CurrencyUnit = Satoshis(Int64(btcToSatoshiScalar))
|
||||
def toSatoshis(unit : CurrencyUnit): Satoshis = unit match {
|
||||
case x : Satoshis => x
|
||||
object Bitcoins extends BaseNumbers[Bitcoins] {
|
||||
val min = Bitcoins((-Consensus.maxMoney).satoshis)
|
||||
val max = Bitcoins(Consensus.maxMoney.satoshis)
|
||||
val zero = Bitcoins(Satoshis.zero)
|
||||
val one = Bitcoins(1)
|
||||
private case class BitcoinsImpl(underlying: BigDecimal) extends Bitcoins
|
||||
|
||||
def apply(underlying: BigDecimal): Bitcoins = BitcoinsImpl(underlying)
|
||||
|
||||
def apply(satoshis: Satoshis): Bitcoins = {
|
||||
val b = satoshis.underlying.underlying * CurrencyUnits.satoshisToBTCScalar
|
||||
BitcoinsImpl(b)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
object CurrencyUnits {
|
||||
def zero: CurrencyUnit = Satoshis.zero
|
||||
def negativeSatoshi = Satoshis(Int64(-1))
|
||||
/** The number you need to multiply BTC by to get it's satoshis */
|
||||
def btcToSatoshiScalar: Long = 100000000
|
||||
def satoshisToBTCScalar: BigDecimal = BigDecimal(1.0) / btcToSatoshiScalar
|
||||
def oneBTC: CurrencyUnit = Satoshis(Int64(btcToSatoshiScalar))
|
||||
|
||||
def toSatoshis(unit : CurrencyUnit): Satoshis = unit match {
|
||||
case b: Bitcoins => b.satoshis
|
||||
case x: Satoshis => x
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,6 +82,8 @@ sealed trait UInt32 extends UnsignedNumber with NumberOperations[UInt32] {
|
|||
|
||||
def & (num : UInt32) : UInt32 = UInt32(underlying & num.underlying)
|
||||
|
||||
|
||||
|
||||
override def hex = BitcoinSUtil.encodeHex(underlying).slice(8,16)
|
||||
|
||||
override def toInt = {
|
||||
|
@ -207,6 +209,7 @@ sealed trait Int32 extends SignedNumber with NumberOperations[Int32] {
|
|||
|
||||
override def <= (num : Int32): Boolean = underlying <= num.underlying
|
||||
|
||||
def unary_- : Int32 = Int32(-underlying)
|
||||
def | (num : Int32) : Int32 = Int32(underlying | num.underlying)
|
||||
|
||||
def & (num : Int32) : Int32 = Int32(underlying & num.underlying)
|
||||
|
@ -261,6 +264,8 @@ sealed trait Int64 extends SignedNumber with NumberOperations[Int64] {
|
|||
|
||||
override def <= (num : Int64): Boolean = underlying <= num.underlying
|
||||
|
||||
def unary_- : Int64 = Int64(-underlying)
|
||||
|
||||
def | (num : Int64) : Int64 = Int64(underlying | num.underlying)
|
||||
|
||||
def & (num : Int64) : Int64 = Int64(underlying & num.underlying)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.bitcoins.core.number
|
||||
|
||||
import org.bitcoins.core.gen.NumberGenerator
|
||||
import org.bitcoins.core.util.BitcoinSLogger
|
||||
import org.scalacheck.{Prop, Properties}
|
||||
|
||||
import scala.util.Try
|
||||
|
@ -8,8 +9,7 @@ import scala.util.Try
|
|||
/**
|
||||
* Created by chris on 6/21/16.
|
||||
*/
|
||||
class Int32Spec extends Properties("Int32Spec") {
|
||||
|
||||
class Int32Spec extends Properties("Int32Spec") with BitcoinSLogger {
|
||||
|
||||
property("Serialization symmetry") =
|
||||
Prop.forAll(NumberGenerator.int32s) { int32: Int32 =>
|
||||
|
@ -86,4 +86,10 @@ class Int32Spec extends Properties("Int32Spec") {
|
|||
Prop.forAll(NumberGenerator.int32s, NumberGenerator.int32s) { (num1: Int32, num2: Int32) =>
|
||||
Int32(num1.underlying & num2.underlying) == (num1 & num2)
|
||||
}
|
||||
|
||||
property("negation") = {
|
||||
Prop.forAll(NumberGenerator.int32s) { int32 =>
|
||||
-int32 == Int32(-int32.underlying)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,5 +86,12 @@ class Int64Spec extends Properties("Int64Spec") {
|
|||
Prop.forAll(NumberGenerator.int64s, NumberGenerator.int64s) { (num1: Int64, num2: Int64) =>
|
||||
Int64(num1.underlying & num2.underlying) == (num1 & num2)
|
||||
}
|
||||
|
||||
property("negation") = {
|
||||
Prop.forAll(NumberGenerator.int64s) { int64 =>
|
||||
-int64 == Int64(-int64.underlying)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue