Small tests i share because why not
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

155 lines
3.7 KiB

  1. #pragma once
  2. #include <type_traits>
  3. #include <iostream>
  4. #pragma GCC diagnostic push
  5. #pragma GCC diagnostic ignored "-Wnarrowing"
  6. namespace ninefloat{
  7. struct private_t{};
  8. private_t priv;
  9. template<class integer_type, int fractionals>
  10. class Q{
  11. integer_type backend;
  12. static constexpr int degen=fractionals;
  13. constexpr Q (const integer_type value, private_t)
  14. : backend{value}
  15. {}
  16. public:
  17. constexpr Q(const Q<integer_type,fractionals>& value)
  18. : backend{value.backend}
  19. {}
  20. template<class srcT>
  21. constexpr Q (const srcT value)
  22. : backend{(integer_type)(value*(1<<degen))}
  23. {}
  24. constexpr Q ()
  25. : backend{0}
  26. {}
  27. constexpr bool is_negative()
  28. {
  29. return backend&(1<<(sizeof(backend)-1));
  30. }
  31. constexpr integer_type data()
  32. {
  33. return backend;
  34. }
  35. constexpr bool is_positive()
  36. {
  37. return !is_negative();
  38. }
  39. constexpr Q<integer_type, fractionals>& operator+=(const Q& oth)
  40. {
  41. backend+=oth.backend;
  42. return *this;
  43. }
  44. constexpr Q<integer_type, fractionals>& operator-=(const Q& oth)
  45. {
  46. backend-=oth.backend;
  47. return *this;
  48. }
  49. constexpr Q<integer_type, fractionals>& operator/=(const Q& oth)
  50. {
  51. backend*=1<<Q<integer_type, fractionals>::degen;
  52. backend/=oth.backend;
  53. return *this;
  54. }
  55. constexpr Q<integer_type, fractionals>& operator*=(const Q& oth)
  56. {
  57. if constexpr(Q<integer_type, fractionals>::degen%2==0)
  58. {
  59. backend=(backend>>(Q<integer_type, fractionals>::degen/2))*(oth.backend>>(Q<integer_type, fractionals>::degen/2));
  60. }else{
  61. backend=(backend>>(Q<integer_type, fractionals>::degen>>1))*(oth.backend>>((Q<integer_type, fractionals>::degen>>1)+1));
  62. }
  63. return *this;
  64. }
  65. constexpr Q<integer_type, fractionals> operator+(const Q& oth)
  66. {
  67. return Q{backend+oth.backend, priv};
  68. }
  69. constexpr Q<integer_type, fractionals> operator-(const Q& oth)
  70. {
  71. return Q{backend-oth.backend, priv};
  72. }
  73. constexpr Q<integer_type, fractionals> operator/(const Q& oth)
  74. {
  75. return Q{(1<<Q<integer_type, fractionals>::degen)*backend/oth.backend, priv};
  76. }
  77. constexpr Q<integer_type, fractionals> operator*(const Q& oth)
  78. {
  79. if constexpr(Q<integer_type, fractionals>::degen%2==0)
  80. {
  81. return Q{(backend>>(Q<integer_type, fractionals>::degen/2))*(oth.backend>>(Q<integer_type, fractionals>::degen/2)),priv};
  82. }else{
  83. return Q{(backend>>(Q<integer_type, fractionals>::degen>>1))*(oth.backend>>((Q<integer_type, fractionals>::degen>>1)+1)),priv};
  84. }
  85. }
  86. constexpr bool operator==(const Q& oth)
  87. {
  88. return backend == oth.backend;
  89. }
  90. constexpr bool operator!=(const Q& oth)
  91. {
  92. return backend != oth.backend;
  93. }
  94. constexpr bool operator>=(const Q& oth)
  95. {
  96. return backend >= oth.backend;
  97. }
  98. constexpr bool operator<=(const Q& oth)
  99. {
  100. return backend <= oth.backend;
  101. }
  102. constexpr bool operator>(const Q& oth)
  103. {
  104. return backend > oth.backend;
  105. }
  106. constexpr bool operator<(const Q& oth)
  107. {
  108. return backend < oth.backend;
  109. }
  110. constexpr operator float()
  111. {
  112. float n=backend;
  113. n/=(1<<Q<integer_type, fractionals>::degen);
  114. return n;
  115. }
  116. constexpr operator double()
  117. {
  118. double n=backend;
  119. n/=(1<<Q<integer_type, fractionals>::degen);
  120. return n;
  121. }
  122. };
  123. #pragma GCC diagnostic pop
  124. }