fl256.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. // Package fl256 implements a fixed-point, '63' decimal precision type.
  2. // The maximum integer value of the "fl256" type is '4,398,046,511,103'.
  3. // It implements a serialization codec for compatibility with big.Float
  4. // that uses a "42.214" fixed-precision value. During calculations, it is
  5. // possible to work with negative numbers for convenience, however, they
  6. // cannot be imported or encoded in "fl256" representation. The functions
  7. // return 'nil' to signify an error condition or when given invalid input.
  8. package fl256
  9. import (
  10. "math/big"
  11. )
  12. // Zero returns a new float, with '256' bits of precision.
  13. // This is a particularly a good way to generate a new variable
  14. // with minimal typing for input conversion functions.
  15. func Zero() *big.Float {
  16. r := big.NewFloat(0.0)
  17. r.SetPrec(256)
  18. return r
  19. }
  20. // New returns a new floating point number with '256' bits
  21. // of precision, containing the desired initial value.
  22. func New(f float64) *big.Float {
  23. r := big.NewFloat(f)
  24. r.SetPrec(256)
  25. return r
  26. }
  27. // FromString accepts a properly formed string of integers or decimal
  28. // values and returns a big.Float to the caller. Negative values, and
  29. // values greater than '4,398,046,511,103' are invalid inputs and will
  30. // be rejected with the function returning 'nil'.
  31. func FromString(s string) *big.Float {
  32. r, success := Zero().SetString(s)
  33. if r.Sign() < 0 {
  34. return nil
  35. }
  36. if r.MantExp(nil) > 42 {
  37. return nil
  38. }
  39. if success {
  40. return r
  41. }
  42. return nil
  43. }
  44. // Int returns the truncated value of the parameter as a *big.Int.
  45. func Int(a *big.Float) *big.Int {
  46. i, _ := a.Int(nil)
  47. return i
  48. }
  49. // FromInt returns a *big.Float from a *big.Int. Negative values and
  50. // values greater than '4,398,046,511,103' are invalid inputs and will
  51. // be rejected by the function, returning 'nil'.
  52. func FromInt(i *big.Int) *big.Float {
  53. r := Zero().SetInt(i)
  54. if r.Sign() < 0 {
  55. return nil
  56. }
  57. if r.MantExp(nil) > 42 {
  58. return nil
  59. }
  60. return r
  61. }
  62. // Int64 returns the value passed as int64, with the decimal truncated.
  63. func Int64(a *big.Float) int64 {
  64. r := Zero()
  65. r.Copy(a)
  66. i, _ := r.Int64()
  67. return i
  68. }
  69. // FromInt64 returns a *big.Float from an int64. Negative values and
  70. // values greater than '4,398,046,511,103' are invalid inputs, and will
  71. // be rejected by the function, returning 'nil'.
  72. func FromInt64(i int64) *big.Float {
  73. r := Zero().SetInt64(i)
  74. if r.Sign() < 0 {
  75. return nil
  76. }
  77. if r.MantExp(nil) > 42 {
  78. return nil
  79. }
  80. return r
  81. }
  82. // Uint64 returns the value passed as a uint64, with the decimal truncated.
  83. func Uint64(a *big.Float) uint64 {
  84. r := Zero()
  85. r.Copy(a)
  86. i, _ := r.Uint64()
  87. return i
  88. }
  89. // FromUint64 returns a *big.Float from a uint64. Values greater than
  90. // '4,398,046,511,103' are invalid inputs, and will and rejected by the
  91. // functions, returning 'nil', as they exceed the precision of "fl256".
  92. func FromUint64(i uint64) *big.Float {
  93. r := Zero().SetUint64(i)
  94. if r.Sign() < 0 {
  95. return nil
  96. }
  97. if r.MantExp(nil) > 42 {
  98. return nil
  99. }
  100. return r
  101. }
  102. // Equal returns true, if 'x' and 'y' are equal.
  103. func Equal(x, y *big.Int) bool {
  104. return x.Cmp(y) == 0
  105. }
  106. // Greater returns true, if ('x' > 'y')
  107. func Greater(x, y *big.Float) bool {
  108. return x.Cmp(y) == 1
  109. }
  110. // Lesser returns true, if ('x' < 'y')
  111. func Lesser(x, y *big.Float) bool {
  112. return x.Cmp(y) == -1
  113. }
  114. // Exp returns ('a' ** 'b')
  115. func Exp(a *big.Float, e uint64) *big.Float {
  116. result := Zero().Copy(a)
  117. for i := uint64(0); i < e-1; i++ {
  118. result = Mul(result, a)
  119. }
  120. return result
  121. }
  122. // Root returns the 'n'th root of 'a' to '255' significant bits.
  123. // XXX(jhj): If it is larger, the function gets stuck in an infinite loop.
  124. func Root(a *big.Float, n uint64) *big.Float {
  125. limit := Exp(New(2), 255)
  126. n1 := n - 1
  127. n1f, rn := New(float64(n1)), Div(New(1.0), New(float64(n)))
  128. x, x0 := New(1.0), Zero()
  129. _ = x0
  130. for {
  131. potx, t2 := Div(New(1.0), x), a
  132. for b := n1; b > 0; b >>= 1 {
  133. if b&1 == 1 {
  134. t2 = Mul(t2, potx)
  135. }
  136. potx = Mul(potx, potx)
  137. }
  138. x0, x = x, Mul(rn, Add(Mul(n1f, x), t2))
  139. if Lesser(Mul(Abs(Sub(x, x0)), limit), x) {
  140. break
  141. }
  142. }
  143. return x
  144. }
  145. // Abs returns 'a', with it's sign set to positive.
  146. func Abs(a *big.Float) *big.Float {
  147. return Zero().Abs(a)
  148. }
  149. // Neg flips the sign of the parameter Float.
  150. // Negative values are rejected by the Encode function.
  151. // (They are invalid in the context of a crypto-currency ledger.)
  152. func Neg(a *big.Float) *big.Float {
  153. return a.Neg(a)
  154. }
  155. // Sign returns '1' for positive,
  156. // '-1' for negative, and '0' for zeros.
  157. func Sign(a *big.Float) int {
  158. return a.Sign()
  159. }
  160. // Sqrt returns the square root of the given parameter.
  161. func Sqrt(a *big.Float) *big.Float {
  162. return Root(a, 2)
  163. }
  164. // Add returns ('a' + 'b')
  165. func Add(a, b *big.Float) *big.Float {
  166. return Zero().Add(a, b)
  167. }
  168. // Sub returns ('a' - 'b')
  169. func Sub(a, b *big.Float) *big.Float {
  170. return Zero().Sub(a, b)
  171. }
  172. // Mul returns ('a' * 'b')
  173. func Mul(a, b *big.Float) *big.Float {
  174. return Zero().Mul(a, b)
  175. }
  176. // Div returns ('a' / 'b')
  177. func Div(a, b *big.Float) *big.Float {
  178. return Zero().Quo(a, b)
  179. }
  180. // Mod returns ('a' % 'b')
  181. func Mod(a, b *big.Float) *big.Float {
  182. q := Div(a, b)
  183. i := Int(q)
  184. fi := Zero().SetInt(i)
  185. rem := Sub(a, Mul(b, fi))
  186. return rem
  187. }
  188. // Encode takes a big.Float input, bit-shifts left, and truncates the
  189. // result at '214' bits of decimal precision, or a maximum of '42' bits
  190. // of integer precision, returning a byte slice. Negative values, and
  191. // values greater than '4,398,046,511,103' are invalid inputs, and will
  192. // be rejected by the function, returning 'nil'.
  193. func Encode(a *big.Float) []byte {
  194. if a.Sign() < 0 {
  195. return nil
  196. }
  197. mantissa := New(0)
  198. a.MantExp(mantissa)
  199. exp := a.MantExp(nil)
  200. if exp > 42 {
  201. return nil
  202. }
  203. bytes := Int(Mul(Exp(New(2), uint64(214+exp)), mantissa)).Bytes()
  204. return append(make([]byte, 32-len(bytes)), bytes...)
  205. }
  206. // Decode takes a value (created by the Encode function), loads it into
  207. // a big.Float, and changes the exponent, shifting the point to '214'
  208. // bits of decimal precision and '42' bits of integer precision (exponent).
  209. func Decode(b []byte) *big.Float {
  210. decoded := big.NewInt(0).SetBytes(b)
  211. decodedF := Zero().SetInt(decoded)
  212. return Zero().SetMantExp(decodedF, -214)
  213. }