fork download
  1. #include <cmath>
  2. #include <iomanip>
  3. #include <iostream>
  4. #include <sstream>
  5. #include <stdint.h>
  6. #include <string>
  7.  
  8. #define MAX(A, B) ((A) > (B) ? (A) : (B))
  9. #define MIN(A, B) ((A) < (B) ? (A) : (B))
  10.  
  11. namespace Astrome
  12. {
  13. typedef uint8_t BitCountType;
  14. typedef uint64_t IntegerDataType;
  15.  
  16. class FixedPoint
  17. {
  18. const BitCountType _totalBits;
  19. const BitCountType _integerBits;
  20. const bool _isSigned;
  21. const IntegerDataType _constant; // This is the number of possible states
  22. const IntegerDataType _factor; // This is the scaling factor
  23. const IntegerDataType _mask;
  24.  
  25. IntegerDataType _integerValue;
  26.  
  27. public:
  28. FixedPoint(BitCountType totalBits,
  29. BitCountType integerBits,
  30. bool isSigned,
  31. IntegerDataType integerValue = 0) :
  32. _totalBits(totalBits),
  33. _integerBits(integerBits), _isSigned(isSigned), _constant(1 << _totalBits),
  34. _factor(1 << (_totalBits - _integerBits)), _mask(_constant - 1),
  35. _integerValue(integerValue & _mask)
  36. {
  37. }
  38.  
  39. FixedPoint(BitCountType totalBits, BitCountType integerBits, bool isSigned, double floatValue) :
  40. FixedPoint(totalBits, integerBits, isSigned, floatToInt(floatValue))
  41. {
  42. }
  43.  
  44.  
  45. IntegerDataType floatToInt(const double &value)
  46. {
  47. if (_isSigned)
  48. {
  49. if (value < 0)
  50. return (round(_constant + value * _factor));
  51. else
  52. return round(value * _factor);
  53. }
  54. else
  55. {
  56. return round(value * _factor);
  57. }
  58. }
  59.  
  60. bool isNegative() const
  61. {
  62. if (_isSigned)
  63. return _integerValue >> (_totalBits - 1);
  64. return false;
  65. }
  66.  
  67. double floatValue() const
  68. {
  69. if (isNegative())
  70. return (_integerValue - _constant) * 1.0 / _factor;
  71. return _integerValue * 1.0 / _factor;
  72. }
  73.  
  74. FixedPoint &operator=(const FixedPoint &other)
  75. {
  76. _integerValue = floatToInt(other.floatValue());
  77. return *this;
  78. }
  79.  
  80. FixedPoint operator>>(const BitCountType &bits)
  81. {
  82. return FixedPoint(_totalBits, _integerBits, _isSigned, _integerValue >> bits);
  83. }
  84.  
  85. FixedPoint operator<<(const BitCountType &bits)
  86. {
  87. IntegerDataType integerValue = _integerValue << bits;
  88. return FixedPoint(_totalBits, _integerBits, _isSigned, integerValue);
  89. }
  90.  
  91. FixedPoint operator-() const
  92. {
  93. return FixedPoint(_totalBits, _integerBits, _isSigned, (~_integerValue) + 1); // Error
  94. }
  95.  
  96. FixedPoint operator+(const FixedPoint &other) const
  97. {
  98. return FixedPoint(_totalBits, _integerBits, _isSigned, floatValue() + other.floatValue());
  99. }
  100.  
  101. FixedPoint operator-(const FixedPoint &other) const
  102. {
  103. return (*this) + (-other);
  104. }
  105.  
  106.  
  107. std::string hexValue() const
  108. {
  109. std::stringstream stream;
  110. stream << "0x" << std::setfill('0') << std::setw(_totalBits / 4) << std::hex << _integerValue;
  111. return (stream.str());
  112. }
  113. };
  114.  
  115. }
  116.  
  117. #ifdef DEBUG
  118. #define PRINT(t, x, f) \
  119.   std::cout << t << "\033[20G" << x.floatValue() << " " << x.hexValue() << "\033[50G" \
  120.   << (fabs(x.floatValue() - f) < 1e-4 ? "OK" : "FAIL") << std::endl;
  121. #else
  122. #define PRINT(t, x, f) std::cout << x.floatValue() << " " << x.hexValue() << std::endl;
  123. #endif
  124.  
  125.  
  126. #define TEST(x) \
  127.   { \
  128.   FixedPoint g(16, 1, true, x); \
  129.   PRINT("X", g, x) \
  130.   \
  131.   FixedPoint h = g >> 1; \
  132.   PRINT("X>>1", h, x / 2) \
  133.   \
  134.   FixedPoint i = h << 1; \
  135.   PRINT("(X>>1)<<1", i, x) \
  136.   \
  137.   FixedPoint j = -g; \
  138.   PRINT("-X", j, -x) \
  139.   \
  140.   FixedPoint k = g + h; \
  141.   PRINT("X + (X>>1)", k, 1.5 * x); \
  142.   \
  143.   FixedPoint l = g - h; \
  144.   PRINT("X - (X>>1)", l, 0.5 * x); \
  145.   std::cout << "-" << std::endl; \
  146.   }
  147.  
  148. int main()
  149. {
  150. using namespace Astrome;
  151.  
  152. TEST(1.0)
  153. TEST(-1.0)
  154. TEST(-0.5)
  155.  
  156. TEST(0.7)
  157. TEST(-0.7)
  158. TEST(M_PI / 4)
  159. }
Success #stdin #stdout 0s 5284KB
stdin
Standard input is empty
stdout
0 0x0000
0 0x0000
0 0x0000
0 0x0000
0 0x0000
0 0x0000
-
5.6295e+14 0x8000
0.5 0x4000
5.6295e+14 0x8000
5.6295e+14 0x8000
5.6295e+14 0xc000
0 0x0000
-
5.6295e+14 0xc000
0.75 0x6000
5.6295e+14 0xc000
0.5 0x4000
0 0x0000
0 0x0000
-
0.700012 0x599a
0.350006 0x2ccd
0.700012 0x599a
5.6295e+14 0xa666
5.6295e+14 0x8667
0 0x0000
-
5.6295e+14 0xa666
0.649994 0x5333
5.6295e+14 0xa666
0.700012 0x599a
5.6295e+14 0xf800
0 0x0000
-
0.7854 0x6488
0.3927 0x3244
0.7854 0x6488
5.6295e+14 0x9b78
5.6295e+14 0x96cc
0 0x0000
-