An implementation of Q floating point format over C++
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.

160 rivejä
3.8 KiB

6 vuotta sitten
  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*(((integer_type)1)<<degen))}
  23. {}
  24. constexpr Q ()
  25. : backend{0}
  26. {}
  27. constexpr static Q min_increment()
  28. {
  29. Q n;
  30. n.backend = 1;
  31. return n;
  32. }
  33. constexpr bool is_negative()
  34. {
  35. return backend&(((integer_type)1)<<(sizeof(backend)-1));
  36. }
  37. constexpr integer_type data()
  38. {
  39. return backend;
  40. }
  41. constexpr bool is_positive()
  42. {
  43. return !is_negative();
  44. }
  45. constexpr Q<integer_type, fractionals>& operator+=(const Q& oth)
  46. {
  47. backend+=oth.backend;
  48. return *this;
  49. }
  50. constexpr Q<integer_type, fractionals>& operator-=(const Q& oth)
  51. {
  52. backend-=oth.backend;
  53. return *this;
  54. }
  55. constexpr Q<integer_type, fractionals>& operator/=(const Q& oth)
  56. {
  57. backend*=((integer_type)1)<<Q<integer_type, fractionals>::degen;
  58. backend/=oth.backend;
  59. return *this;
  60. }
  61. constexpr Q<integer_type, fractionals>& operator*=(const Q& oth)
  62. {
  63. if constexpr(Q<integer_type, fractionals>::degen%2==0)
  64. {
  65. backend=(backend>>(Q<integer_type, fractionals>::degen/2))*(oth.backend>>(Q<integer_type, fractionals>::degen/2));
  66. }else{
  67. backend=(backend>>(Q<integer_type, fractionals>::degen>>1))*(oth.backend>>((Q<integer_type, fractionals>::degen>>1)+1));
  68. }
  69. return *this;
  70. }
  71. constexpr Q<integer_type, fractionals> operator+(const Q& oth)
  72. {
  73. return Q{backend+oth.backend, priv};
  74. }
  75. constexpr Q<integer_type, fractionals> operator-(const Q& oth)
  76. {
  77. return Q{backend-oth.backend, priv};
  78. }
  79. constexpr Q<integer_type, fractionals> operator/(const Q& oth)
  80. {
  81. return Q{(1<<Q<integer_type, fractionals>::degen)*backend/oth.backend, priv};
  82. }
  83. constexpr Q<integer_type, fractionals> operator*(const Q& oth)
  84. {
  85. if constexpr(Q<integer_type, fractionals>::degen%2==0)
  86. {
  87. return Q{(backend>>(Q<integer_type, fractionals>::degen/2))*(oth.backend>>(Q<integer_type, fractionals>::degen/2)),priv};
  88. }else{
  89. return Q{(backend>>(Q<integer_type, fractionals>::degen>>1))*(oth.backend>>((Q<integer_type, fractionals>::degen>>1)+1)),priv};
  90. }
  91. }
  92. constexpr bool operator==(const Q& oth)
  93. {
  94. return backend == oth.backend;
  95. }
  96. constexpr bool operator!=(const Q& oth)
  97. {
  98. return backend != oth.backend;
  99. }
  100. constexpr bool operator>=(const Q& oth)
  101. {
  102. return backend >= oth.backend;
  103. }
  104. constexpr bool operator<=(const Q& oth)
  105. {
  106. return backend <= oth.backend;
  107. }
  108. constexpr bool operator>(const Q& oth)
  109. {
  110. return backend > oth.backend;
  111. }
  112. constexpr bool operator<(const Q& oth)
  113. {
  114. return backend < oth.backend;
  115. }
  116. constexpr operator float()
  117. {
  118. float n=backend;
  119. n/=(((integer_type)1)<<Q<integer_type, fractionals>::degen);
  120. return n;
  121. }
  122. constexpr operator double()
  123. {
  124. double n=backend;
  125. n/=(((integer_type)1)<<Q<integer_type, fractionals>::degen);
  126. return n;
  127. }
  128. };
  129. #pragma GCC diagnostic pop
  130. }