BigInt.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. // Copyright (c) 2008-2023 the Urho3D project
  2. // License: MIT
  3. #pragma once
  4. #include "../Container/Str.h"
  5. #include "../Container/Vector.h"
  6. #include "MathDefs.h"
  7. namespace Urho3D
  8. {
  9. class URHO3D_API BigInt
  10. {
  11. public:
  12. /// i64 can conatins 10^9 * 10^9.
  13. using Digit = i64;
  14. private:
  15. /// Sign (zero is positive).
  16. bool positive_;
  17. /// Array of digits with base 10^9 and reverse order (each element contains value in range [0 .. BASE-1]).
  18. Vector<Digit> magnitude_;
  19. public:
  20. BigInt();
  21. BigInt(const String& str);
  22. BigInt(i32 value);
  23. BigInt(i64 value);
  24. BigInt(u32 value);
  25. BigInt(u64 value);
  26. bool IsPositive() const { return positive_; }
  27. bool IsNegative() const { return !positive_; }
  28. bool IsZero() const;
  29. bool operator ==(const BigInt& rhs) const { return positive_ == rhs.positive_ && magnitude_ == rhs.magnitude_; }
  30. bool operator !=(const BigInt& rhs) const { return positive_ != rhs.positive_ || magnitude_ != rhs.magnitude_; }
  31. bool operator <(const BigInt& rhs) const;
  32. bool operator >(const BigInt& rhs) const { return rhs < *this; }
  33. bool operator <=(const BigInt& rhs) const { return *this == rhs || *this < rhs; }
  34. bool operator >=(const BigInt& rhs) const { return *this == rhs || *this > rhs; }
  35. BigInt operator +(const BigInt& rhs) const;
  36. BigInt operator -(const BigInt& rhs) const;
  37. BigInt operator *(const BigInt& rhs) const;
  38. /// Return 0 if rhs zero.
  39. BigInt operator /(const BigInt& rhs) const;
  40. /// Return 0 if rhs zero.
  41. BigInt operator %(const BigInt& rhs) const;
  42. BigInt operator -() const;
  43. BigInt& operator +=(const BigInt& rhs);
  44. BigInt& operator -=(const BigInt& rhs);
  45. BigInt& operator *=(const BigInt& rhs);
  46. BigInt& operator /=(const BigInt& rhs);
  47. BigInt& operator %=(const BigInt& rhs);
  48. /// Prefix increment operator.
  49. BigInt& operator++() { this->operator +=(1); return *this; }
  50. /// Postfix increment operator.
  51. BigInt operator++(int x) { BigInt ret = *this; ++*this; return ret; }
  52. /// Prefix decrement operator.
  53. BigInt& operator--() { this->operator -=(1); return *this; }
  54. /// Postfix decrement operator.
  55. BigInt operator--(int x) { BigInt ret = *this; --*this; return ret; }
  56. String ToString() const;
  57. };
  58. #if false // Without constraints this can cause conflicts
  59. template <typename T> BigInt operator +(T lhs, const BigInt& rhs) { return BigInt(lhs) + rhs; }
  60. template <typename T> BigInt operator -(T lhs, const BigInt& rhs) { return BigInt(lhs) - rhs; }
  61. template <typename T> BigInt operator *(T lhs, const BigInt& rhs) { return BigInt(lhs) * rhs; }
  62. template <typename T> BigInt operator /(T lhs, const BigInt& rhs) { return BigInt(lhs) / rhs; }
  63. template <typename T> BigInt operator %(T lhs, const BigInt& rhs) { return BigInt(lhs) % rhs; }
  64. #else
  65. inline BigInt operator +(i32 lhs, const BigInt& rhs) { return BigInt(lhs) + rhs; }
  66. inline BigInt operator +(u32 lhs, const BigInt& rhs) { return BigInt(lhs) + rhs; }
  67. inline BigInt operator +(i64 lhs, const BigInt& rhs) { return BigInt(lhs) + rhs; }
  68. inline BigInt operator +(u64 lhs, const BigInt& rhs) { return BigInt(lhs) + rhs; }
  69. inline BigInt operator -(i32 lhs, const BigInt& rhs) { return BigInt(lhs) - rhs; }
  70. inline BigInt operator -(u32 lhs, const BigInt& rhs) { return BigInt(lhs) - rhs; }
  71. inline BigInt operator -(i64 lhs, const BigInt& rhs) { return BigInt(lhs) - rhs; }
  72. inline BigInt operator -(u64 lhs, const BigInt& rhs) { return BigInt(lhs) - rhs; }
  73. inline BigInt operator *(i32 lhs, const BigInt& rhs) { return BigInt(lhs) * rhs; }
  74. inline BigInt operator *(u32 lhs, const BigInt& rhs) { return BigInt(lhs) * rhs; }
  75. inline BigInt operator *(i64 lhs, const BigInt& rhs) { return BigInt(lhs) * rhs; }
  76. inline BigInt operator *(u64 lhs, const BigInt& rhs) { return BigInt(lhs) * rhs; }
  77. inline BigInt operator /(i32 lhs, const BigInt& rhs) { return BigInt(lhs) / rhs; }
  78. inline BigInt operator /(u32 lhs, const BigInt& rhs) { return BigInt(lhs) / rhs; }
  79. inline BigInt operator /(i64 lhs, const BigInt& rhs) { return BigInt(lhs) / rhs; }
  80. inline BigInt operator /(u64 lhs, const BigInt& rhs) { return BigInt(lhs) / rhs; }
  81. inline BigInt operator %(i32 lhs, const BigInt& rhs) { return BigInt(lhs) % rhs; }
  82. inline BigInt operator %(u32 lhs, const BigInt& rhs) { return BigInt(lhs) % rhs; }
  83. inline BigInt operator %(i64 lhs, const BigInt& rhs) { return BigInt(lhs) % rhs; }
  84. inline BigInt operator %(u64 lhs, const BigInt& rhs) { return BigInt(lhs) % rhs; }
  85. #endif
  86. inline BigInt Abs(const BigInt& value) { return value.IsNegative() ? -value : value; }
  87. } // namespace Urho3D