go-randomx/math.go
DataHoarder 36f1a90a20
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
Version v3.0.0, support full datataset mode in 64-bit targets, modified api, optimized allocations, full VM run JIT on amd64, optimize AES asm
2024-04-23 04:33:42 +02:00

80 lines
2 KiB
Go

package randomx
import (
"math"
"math/bits"
)
const (
mantbits64 uint = 52
expbits64 uint = 11
)
const mantissaMask = (uint64(1) << mantbits64) - 1
const exponentMask = (uint64(1) << expbits64) - 1
const exponentBias = 1023
const dynamicExponentBits = 4
const staticExponentBits = 4
const constExponentBits uint64 = 0x300
const dynamicMantissaMask = (uint64(1) << (mantbits64 + dynamicExponentBits)) - 1
const mask22bit = (uint64(1) << 22) - 1
func MaskRegisterExponentMantissa(f float64, mode uint64) float64 {
return math.Float64frombits((math.Float64bits(f) & dynamicMantissaMask) | mode)
}
func ScaleNegate(f float64) float64 {
return math.Float64frombits(math.Float64bits(f) ^ 0x80F0000000000000)
}
func SmallPositiveFloatBits(entropy uint64) float64 {
exponent := entropy >> 59 //0..31
mantissa := entropy & mantissaMask
exponent += exponentBias
exponent &= exponentMask
exponent = exponent << mantbits64
return math.Float64frombits(exponent | mantissa)
}
func StaticExponent(entropy uint64) uint64 {
exponent := constExponentBits
exponent |= (entropy >> (64 - staticExponentBits)) << dynamicExponentBits
exponent <<= mantbits64
return exponent
}
func ExponentMask(entropy uint64) uint64 {
return (entropy & mask22bit) | StaticExponent(entropy)
}
func Xor(a, b float64) float64 {
return math.Float64frombits(math.Float64bits(a) ^ math.Float64bits(b))
}
func smulh(a, b int64) uint64 {
hi_, _ := bits.Mul64(uint64(a), uint64(b))
t1 := (a >> 63) & b
t2 := (b >> 63) & a
return uint64(int64(hi_) - t1 - t2)
}
// reciprocal
// Calculates rcp = 2**x / divisor for highest integer x such that rcp < 2**64.
// divisor must not be 0 or a power of 2
func reciprocal(divisor uint32) uint64 {
const p2exp63 = uint64(1) << 63
quotient := p2exp63 / uint64(divisor)
remainder := p2exp63 % uint64(divisor)
shift := bits.Len32(divisor)
return (quotient << shift) + ((remainder << shift) / uint64(divisor))
}
func signExtend2sCompl(x uint32) uint64 {
return uint64(int64(int32(x)))
}