Advertisement
Guest User

Untitled

a guest
Jul 24th, 2017
54
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.43 KB | None | 0 0
  1. //ArmanDoesStuff 2017
  2. //MegaInt version 1.0
  3. #if UNITY_EDITOR
  4. using UnityEngine;
  5. #endif
  6.  
  7. namespace System.Collections
  8. {
  9. public class MegaInt
  10. {
  11. #region variables
  12. string[] PowerNames = new string[]
  13. {
  14. "", "Thousand", "Million", "Billion", "Trillion", "Quadrillion", "Quintillion", "Sextillion", "Septillion",
  15. "Octillion", "Nonillion", "Decillion", "Undecillion", "Duodecillion", "Tredecillion", "Quattuordecillion",
  16. "Quindecillion", "Sexdecillion", "Septendecillion", "Octodecillion", "Novemdecillion", "Vigintillion"
  17. };
  18.  
  19. uint storedValue; //actual data, holds Value and Power
  20. #endregion
  21.  
  22. #region accessors
  23. //First 8 bits are Power (up to 10^255)
  24. byte Power
  25. {
  26. get
  27. {
  28. //return as byte (pushed to rightmost two bits, Val overridden)
  29. return (byte)(storedValue >> 24);
  30. }
  31. set
  32. {
  33. //set as left bits, add original Val
  34. storedValue = (uint)(value << 24) + (storedValue & 16777215);
  35. }
  36. }
  37.  
  38. //Last 24 are Value(16777216 - accuracy to 7 - 9999999)
  39. uint Val
  40. {
  41. get
  42. {
  43. //return with Power masked out
  44. return (storedValue & 16777215); //16777215 = 0000 0000 1111 1111 1111 1111 1111 1111
  45. }
  46. set
  47. {
  48. //set unmasked since the Power bits should never be set anyway. Add original Power to left bits
  49. storedValue = (uint)((value /* & 16777215 */) + (Power << 24));
  50. }
  51. }
  52. #endregion
  53.  
  54. #region functions
  55.  
  56. //divide by power of 10
  57. public static MegaInt Pow10Div(MegaInt a, byte p)
  58. {
  59. //get power difference
  60. int outPower = a.Power - p;
  61. if (outPower < 0)
  62. {
  63. string outValString = a.Val.ToString();
  64. //take off last digets to the amount of power or until only one remains
  65. return ulong.Parse(outValString.Substring(0, outValString.Length - Math.Min(Math.Abs(outPower), outValString.Length - 1)));
  66. }
  67. else
  68. {
  69. //if there is power remaining after divide, just output val with new power
  70. return new MegaInt(a.Val, (byte)outPower);
  71. }
  72. }
  73.  
  74. public MegaInt Pow10Div(byte p)
  75. {
  76. return Pow10Div(this, p);
  77. }
  78.  
  79. //divide by mult of 10
  80. public static MegaInt Pow10Mult(MegaInt a, byte p)
  81. {
  82. //get power difference
  83. return new MegaInt(a.Val, (byte)(a.Power + p));
  84. }
  85.  
  86. public MegaInt Pow10Mult(byte p)
  87. {
  88. return Pow10Mult(this, p);
  89. }
  90.  
  91. //divide by power of 10, round up
  92. public static uint OverPowerDiff(MegaInt a, byte highPower)
  93. {
  94. return (uint)((a.Val - 1) / (Math.Pow(10, highPower - a.Power))) + 1;
  95. }
  96.  
  97. uint[] ConvertToMega(string a)
  98. {
  99. return ConvertToMega(a, 0);
  100. }
  101.  
  102. //Power Function
  103. public static MegaInt PowerMult(MegaInt init, MegaInt mult, int pow)
  104. {
  105. for (int i = 0; i < pow; i++)
  106. {
  107. init *= mult;
  108. }
  109. return init;
  110. }
  111.  
  112. uint[] ConvertToMega(string a, byte p)
  113. {
  114. //normalise to 7 digits if there is power
  115. while (a.Length < 7 && p > 0)
  116. {
  117. a += "0";
  118. p--;
  119. }
  120.  
  121. //accuracy to 7 digits since 24-bits go up to 16777216 - 8 characters
  122. while (a.Length > 7)
  123. {
  124. //remove end number and increase power of 10 by one
  125. a = a.Remove(a.Length - 1);
  126. p++;
  127. }
  128. //return as values suitable for variables
  129. return new uint[2] { uint.Parse(a), p };
  130. }
  131.  
  132. #region constuctors
  133. public MegaInt(ulong a)
  134. {
  135. uint[] i = ConvertToMega(a.ToString());
  136. Val = i[0];
  137. Power = (byte)i[1];
  138. }
  139.  
  140. public MegaInt(uint a)
  141. {
  142. uint[] i = ConvertToMega(a.ToString());
  143. Val = i[0];
  144. Power = (byte)i[1];
  145. }
  146.  
  147. public MegaInt(ulong a, byte p)
  148. {
  149. uint[] i = ConvertToMega(a.ToString(), p);
  150. Val = i[0];
  151. Power = (byte)i[1];
  152. }
  153.  
  154. public MegaInt(string a)
  155. {
  156. #if UNITY_EDITOR
  157. //Sanitized input check. Might waste memory, only activate if using user input to MegaInt.
  158. a = a.TrimStart('0');
  159. if (!a.IsDigitsOnly() || a == "")
  160. {
  161. Val = 0;
  162. Power = 0;
  163. return;
  164. }
  165. #endif
  166. uint[] i = ConvertToMega(a);
  167. Val = i[0];
  168. Power = (byte)i[1];
  169.  
  170. }
  171. #endregion
  172.  
  173. #region implicits
  174. public static implicit operator MegaInt(string a)
  175. {
  176. return new MegaInt(a);
  177. }
  178.  
  179. public static implicit operator MegaInt(uint a)
  180. {
  181. return new MegaInt(a);
  182. }
  183.  
  184. public static implicit operator MegaInt(ulong a)
  185. {
  186. return new MegaInt(a);
  187. }
  188.  
  189. public static implicit operator string(MegaInt a)
  190. {
  191. return a.ToString();
  192. }
  193. #endregion
  194.  
  195. #region overrides
  196. public override string ToString()
  197. {
  198. if (Val < 1000) //only act on Values above 1 thousand
  199. {
  200. return Val.ToString();
  201. }
  202.  
  203. //the higher the power the further the point moves until it resets at 10^3 to x.xxx
  204. int digits = Power + (Val.ToString().Length); //number of digits
  205. if (digits > 66) //if above Vigintillion then just show power
  206. {
  207. return Val.ToString().Substring(0, 4).Insert(1, ".") + " 10^" + digits;
  208. }
  209. int decimalPlace = digits % 3 == 0 ? 3 : digits % 3; // + (Value < 0 ? 1 : 0); if doing negetives
  210. //get first 4 digits as significant figures
  211. //Add decimal point at correct place (as described above)
  212. //add power name (power, plus extra power for length minus the first 3) over 3 for because increments are 10^3
  213. return Val.ToString().Substring(0, 4).Insert(decimalPlace, ".") + " " + PowerNames[(digits - 1) / 3];
  214. }
  215.  
  216. public override bool Equals(object obj)
  217. {
  218. var item = obj as MegaInt;
  219.  
  220. if (item == null)
  221. {
  222. return false;
  223. }
  224.  
  225. return this.storedValue.Equals(item.storedValue);
  226. }
  227.  
  228. public override int GetHashCode()
  229. {
  230. return this.storedValue.GetHashCode();
  231. }
  232.  
  233. #region equalities
  234. public static bool operator <(MegaInt leftSide, MegaInt rightSide)
  235. {
  236. //check powers, then check values (if powers are equal)
  237. if (leftSide.Power < rightSide.Power || (leftSide.Power == rightSide.Power && leftSide.Val < rightSide.Val))
  238. {
  239. return true;
  240. }
  241. return false;
  242. }
  243.  
  244. public static bool operator >(MegaInt leftSide, MegaInt rightSide)
  245. {
  246. //same as above (with signs switched)
  247. if (leftSide.Power > rightSide.Power || (leftSide.Power == rightSide.Power && leftSide.Val > rightSide.Val))
  248. {
  249. return true;
  250. }
  251. return false;
  252. }
  253.  
  254. public static bool operator ==(MegaInt leftSide, MegaInt rightSide)
  255. {
  256. //powers AND values must match
  257. if (leftSide.storedValue == rightSide.storedValue) //(leftSide.Val == rightSide.Val && leftSide.Power == rightSide.Power)
  258. {
  259. return true;
  260. }
  261. return false;
  262. }
  263.  
  264. public static bool operator !=(MegaInt leftSide, MegaInt rightSide)
  265. {
  266. //defined above then inverted
  267. if (leftSide == rightSide)
  268. {
  269. return false;
  270. }
  271. return true;
  272. }
  273. #endregion
  274.  
  275. #region enumeration
  276. //get higher power of both values and calculate based on that
  277. public static MegaInt operator +(MegaInt leftSide, MegaInt rightSide)
  278. {
  279. byte highPower = (byte)Math.Max(leftSide.Power, rightSide.Power);
  280. ulong totalVal = OverPowerDiff(leftSide, highPower) + OverPowerDiff(rightSide, highPower);
  281. return new MegaInt(totalVal, highPower);
  282. }
  283.  
  284. public static MegaInt operator -(MegaInt leftSide, MegaInt rightSide)
  285. {
  286. if (rightSide > leftSide) { return 0; }
  287. if (leftSide.Power - rightSide.Power > 7) { return leftSide; }
  288. ulong totalVal = leftSide.Val - (OverPowerDiff(rightSide, leftSide.Power));
  289. return new MegaInt(totalVal, leftSide.Power);
  290. }
  291.  
  292. public static MegaInt operator *(MegaInt leftSide, MegaInt rightSide)
  293. {
  294. return new MegaInt((ulong)leftSide.Val * (ulong)rightSide.Val, (byte)(leftSide.Power + rightSide.Power));
  295. }
  296.  
  297. public static MegaInt operator /(MegaInt leftSide, MegaInt rightSide)
  298. {
  299. return new MegaInt(((ulong)(leftSide.Val - 1) / (ulong)rightSide.Val) + 1, (byte)(leftSide.Power - rightSide.Power));
  300. }
  301. #endregion
  302.  
  303. #endregion
  304.  
  305. #endregion
  306. }
  307. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement