github.com/filecoin-project/specs-actors/v4@v4.0.2/actors/builtin/miner/quantize.go (about) 1 package miner 2 3 import "github.com/filecoin-project/go-state-types/abi" 4 5 // A spec for quantization. 6 type QuantSpec struct { 7 unit abi.ChainEpoch // The unit of quantization 8 offset abi.ChainEpoch // The offset from zero from which to base the modulus 9 } 10 11 func NewQuantSpec(unit, offset abi.ChainEpoch) QuantSpec { 12 return QuantSpec{unit: unit, offset: offset} 13 } 14 15 func (q QuantSpec) QuantizeUp(e abi.ChainEpoch) abi.ChainEpoch { 16 return quantizeUp(e, q.unit, q.offset) 17 } 18 19 func (q QuantSpec) QuantizeDown(e abi.ChainEpoch) abi.ChainEpoch { 20 next := q.QuantizeUp(e) 21 // QuantizeDown == QuantizeUp iff e is a fixed point of QuantizeUp 22 if e == next { 23 return next 24 } 25 return next - q.unit 26 } 27 28 var NoQuantization = NewQuantSpec(1, 0) 29 30 // Rounds e to the nearest exact multiple of the quantization unit offset by 31 // offsetSeed % unit, rounding up. 32 // This function is equivalent to `unit * ceil(e - (offsetSeed % unit) / unit) + (offsetSeed % unit)` 33 // with the variables/operations are over real numbers instead of ints. 34 // Precondition: unit >= 0 else behaviour is undefined 35 func quantizeUp(e abi.ChainEpoch, unit abi.ChainEpoch, offsetSeed abi.ChainEpoch) abi.ChainEpoch { 36 offset := offsetSeed % unit 37 38 remainder := (e - offset) % unit 39 quotient := (e - offset) / unit 40 // Don't round if epoch falls on a quantization epoch 41 if remainder == 0 { 42 return unit*quotient + offset 43 } 44 // Negative truncating division rounds up 45 if e-offset < 0 { 46 return unit*quotient + offset 47 } 48 return unit*(quotient+1) + offset 49 50 }