SimpleBigDecimal.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.Text;
  5. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Abc
  6. {
  7. /**
  8. * Class representing a simple version of a big decimal. A
  9. * <code>SimpleBigDecimal</code> is basically a
  10. * {@link java.math.BigInteger BigInteger} with a few digits on the right of
  11. * the decimal point. The number of (binary) digits on the right of the decimal
  12. * point is called the <code>scale</code> of the <code>SimpleBigDecimal</code>.
  13. * Unlike in {@link java.math.BigDecimal BigDecimal}, the scale is not adjusted
  14. * automatically, but must be set manually. All <code>SimpleBigDecimal</code>s
  15. * taking part in the same arithmetic operation must have equal scale. The
  16. * result of a multiplication of two <code>SimpleBigDecimal</code>s returns a
  17. * <code>SimpleBigDecimal</code> with double scale.
  18. */
  19. internal class SimpleBigDecimal
  20. // : Number
  21. {
  22. // private static final long serialVersionUID = 1L;
  23. private readonly BigInteger bigInt;
  24. private readonly int scale;
  25. /**
  26. * Returns a <code>SimpleBigDecimal</code> representing the same numerical
  27. * value as <code>value</code>.
  28. * @param value The value of the <code>SimpleBigDecimal</code> to be
  29. * created.
  30. * @param scale The scale of the <code>SimpleBigDecimal</code> to be
  31. * created.
  32. * @return The such created <code>SimpleBigDecimal</code>.
  33. */
  34. public static SimpleBigDecimal GetInstance(BigInteger val, int scale)
  35. {
  36. return new SimpleBigDecimal(val.ShiftLeft(scale), scale);
  37. }
  38. /**
  39. * Constructor for <code>SimpleBigDecimal</code>. The value of the
  40. * constructed <code>SimpleBigDecimal</code> Equals <code>bigInt /
  41. * 2<sup>scale</sup></code>.
  42. * @param bigInt The <code>bigInt</code> value parameter.
  43. * @param scale The scale of the constructed <code>SimpleBigDecimal</code>.
  44. */
  45. public SimpleBigDecimal(BigInteger bigInt, int scale)
  46. {
  47. if (scale < 0)
  48. throw new ArgumentException("scale may not be negative");
  49. this.bigInt = bigInt;
  50. this.scale = scale;
  51. }
  52. private SimpleBigDecimal(SimpleBigDecimal limBigDec)
  53. {
  54. bigInt = limBigDec.bigInt;
  55. scale = limBigDec.scale;
  56. }
  57. private void CheckScale(SimpleBigDecimal b)
  58. {
  59. if (scale != b.scale)
  60. throw new ArgumentException("Only SimpleBigDecimal of same scale allowed in arithmetic operations");
  61. }
  62. public SimpleBigDecimal AdjustScale(int newScale)
  63. {
  64. if (newScale < 0)
  65. throw new ArgumentException("scale may not be negative");
  66. if (newScale == scale)
  67. return this;
  68. return new SimpleBigDecimal(bigInt.ShiftLeft(newScale - scale), newScale);
  69. }
  70. public SimpleBigDecimal Add(SimpleBigDecimal b)
  71. {
  72. CheckScale(b);
  73. return new SimpleBigDecimal(bigInt.Add(b.bigInt), scale);
  74. }
  75. public SimpleBigDecimal Add(BigInteger b)
  76. {
  77. return new SimpleBigDecimal(bigInt.Add(b.ShiftLeft(scale)), scale);
  78. }
  79. public SimpleBigDecimal Negate()
  80. {
  81. return new SimpleBigDecimal(bigInt.Negate(), scale);
  82. }
  83. public SimpleBigDecimal Subtract(SimpleBigDecimal b)
  84. {
  85. return Add(b.Negate());
  86. }
  87. public SimpleBigDecimal Subtract(BigInteger b)
  88. {
  89. return new SimpleBigDecimal(bigInt.Subtract(b.ShiftLeft(scale)), scale);
  90. }
  91. public SimpleBigDecimal Multiply(SimpleBigDecimal b)
  92. {
  93. CheckScale(b);
  94. return new SimpleBigDecimal(bigInt.Multiply(b.bigInt), scale + scale);
  95. }
  96. public SimpleBigDecimal Multiply(BigInteger b)
  97. {
  98. return new SimpleBigDecimal(bigInt.Multiply(b), scale);
  99. }
  100. public SimpleBigDecimal Divide(SimpleBigDecimal b)
  101. {
  102. CheckScale(b);
  103. BigInteger dividend = bigInt.ShiftLeft(scale);
  104. return new SimpleBigDecimal(dividend.Divide(b.bigInt), scale);
  105. }
  106. public SimpleBigDecimal Divide(BigInteger b)
  107. {
  108. return new SimpleBigDecimal(bigInt.Divide(b), scale);
  109. }
  110. public SimpleBigDecimal ShiftLeft(int n)
  111. {
  112. return new SimpleBigDecimal(bigInt.ShiftLeft(n), scale);
  113. }
  114. public int CompareTo(SimpleBigDecimal val)
  115. {
  116. CheckScale(val);
  117. return bigInt.CompareTo(val.bigInt);
  118. }
  119. public int CompareTo(BigInteger val)
  120. {
  121. return bigInt.CompareTo(val.ShiftLeft(scale));
  122. }
  123. public BigInteger Floor()
  124. {
  125. return bigInt.ShiftRight(scale);
  126. }
  127. public BigInteger Round()
  128. {
  129. SimpleBigDecimal oneHalf = new SimpleBigDecimal(BigInteger.One, 1);
  130. return Add(oneHalf.AdjustScale(scale)).Floor();
  131. }
  132. public int IntValue
  133. {
  134. get { return Floor().IntValue; }
  135. }
  136. public long LongValue
  137. {
  138. get { return Floor().LongValue; }
  139. }
  140. // public double doubleValue()
  141. // {
  142. // return new Double(ToString()).doubleValue();
  143. // }
  144. //
  145. // public float floatValue()
  146. // {
  147. // return new Float(ToString()).floatValue();
  148. // }
  149. public int Scale
  150. {
  151. get { return scale; }
  152. }
  153. public override string ToString()
  154. {
  155. if (scale == 0)
  156. return bigInt.ToString();
  157. BigInteger floorBigInt = Floor();
  158. BigInteger fract = bigInt.Subtract(floorBigInt.ShiftLeft(scale));
  159. if (bigInt.SignValue < 0)
  160. {
  161. fract = BigInteger.One.ShiftLeft(scale).Subtract(fract);
  162. }
  163. if ((floorBigInt.SignValue == -1) && (!(fract.Equals(BigInteger.Zero))))
  164. {
  165. floorBigInt = floorBigInt.Add(BigInteger.One);
  166. }
  167. string leftOfPoint = floorBigInt.ToString();
  168. char[] fractCharArr = new char[scale];
  169. string fractStr = fract.ToString(2);
  170. int fractLen = fractStr.Length;
  171. int zeroes = scale - fractLen;
  172. for (int i = 0; i < zeroes; i++)
  173. {
  174. fractCharArr[i] = '0';
  175. }
  176. for (int j = 0; j < fractLen; j++)
  177. {
  178. fractCharArr[zeroes + j] = fractStr[j];
  179. }
  180. string rightOfPoint = new string(fractCharArr);
  181. StringBuilder sb = new StringBuilder(leftOfPoint);
  182. sb.Append(".");
  183. sb.Append(rightOfPoint);
  184. return sb.ToString();
  185. }
  186. public override bool Equals(
  187. object obj)
  188. {
  189. if (this == obj)
  190. return true;
  191. SimpleBigDecimal other = obj as SimpleBigDecimal;
  192. if (other == null)
  193. return false;
  194. return bigInt.Equals(other.bigInt)
  195. && scale == other.scale;
  196. }
  197. public override int GetHashCode()
  198. {
  199. return bigInt.GetHashCode() ^ scale;
  200. }
  201. }
  202. }
  203. #pragma warning restore
  204. #endif