fork download
  1. #include <iostream>
  2. #include <limits>
  3. #include <cmath>
  4.  
  5. template <typename precission_t>
  6. struct encoded_floating_point
  7. {
  8. using type = precission_t;
  9. static constexpr auto max { std::numeric_limits<precission_t>::max() };
  10.  
  11. const int exponent {};
  12. const type mantissa {};
  13. };
  14.  
  15. using encoded_float = encoded_floating_point<std::uint32_t>;
  16. using encoded_double = encoded_floating_point<std::uint64_t>;
  17.  
  18. encoded_float encode_f(float value)
  19. {
  20. int exponent {};
  21. encoded_float::type mantissa { encoded_float::max * std::frexp(value, &exponent) };
  22.  
  23. return {exponent, mantissa};
  24. }
  25.  
  26. float decode_f(const encoded_float &encoded)
  27. {
  28. return std::ldexp(float {encoded.mantissa} / encoded_float::max, encoded.exponent);
  29. }
  30.  
  31. encoded_double encode_d(double value)
  32. {
  33. int exponent {};
  34. encoded_double::type mantissa { encoded_double::max * std::frexp(value, &exponent) };
  35.  
  36. return {exponent, mantissa};
  37. }
  38.  
  39. double decode_d(const encoded_double &encoded)
  40. {
  41. return std::ldexp(double {encoded.mantissa} / encoded_double::max, encoded.exponent);
  42. }
  43.  
  44. template <typename FPN> FPN test_numbers[]
  45. {
  46. 1. / 3., 2. / 3., 3. / 3., 4. / 3., 5. / 3.,
  47. 1. / 6., 2. / 6., 3. / 6., 4. / 6., 5. / 6.,
  48. 1. / 7., 2. / 7., 3. / 7., 4. / 7., 5. / 7.,
  49. 1. / 9., 2. / 9., 3. / 9., 4. / 9., 5. / 9.,
  50. 1. / 11., 2. / 11., 3. / 11., 4. / 11., 5. / 11.,
  51. 1. / 13., 2. / 13., 3. / 13., 4. / 13., 5. / 13.
  52. };
  53.  
  54. int main()
  55. {
  56. std::cout.precision(std::numeric_limits<float>::max_digits10);
  57. for (const auto &f : test_numbers<float>)
  58. {
  59. const auto x = encode_f(f);
  60. std::cout << f << ' ' << x.exponent << ' ' << x.mantissa << '\n'
  61. << decode_f(x) << '\n' << '\n';
  62. }
  63.  
  64. std::cout.precision(std::numeric_limits<double>::max_digits10);
  65. for (const auto &d : test_numbers<double>)
  66. {
  67. const auto x = encode_d(d);
  68. std::cout << d << ' ' << x.exponent << ' ' << x.mantissa << '\n'
  69. << decode_d(x) << '\n' << '\n';
  70. }
  71. return 0;
  72. }
Success #stdin #stdout 0s 3468KB
stdin
Standard input is empty
stdout
0.333333343 -1 2863311616
0.333333343

0.666666687 0 2863311616
0.666666687

1 1 2147483648
1

1.33333337 1 2863311616
1.33333337

1.66666663 1 3579139328
1.66666663

0.166666672 -2 2863311616
0.166666672

0.333333343 -1 2863311616
0.333333343

0.5 0 2147483648
0.5

0.666666687 0 2863311616
0.666666687

0.833333313 0 3579139328
0.833333313

0.142857149 -2 2454267136
0.142857149

0.285714298 -1 2454267136
0.285714298

0.428571433 -1 3681400576
0.428571433

0.571428597 0 2454267136
0.571428597

0.714285731 0 3067833856
0.714285731

0.111111112 -3 3817748736
0.111111112

0.222222224 -2 3817748736
0.222222224

0.333333343 -1 2863311616
0.333333343

0.444444448 -1 3817748736
0.444444448

0.555555582 0 2386093056
0.555555582

0.0909090936 -3 3123612672
0.0909090936

0.181818187 -2 3123612672
0.181818187

0.272727281 -1 2342709504
0.272727281

0.363636374 -1 3123612672
0.363636374

0.454545468 -1 3904515840
0.454545468

0.0769230798 -3 2643056896
0.0769230798

0.15384616 -2 2643056896
0.15384616

0.230769232 -2 3964585216
0.230769232

0.307692319 -1 2643056896
0.307692319

0.384615391 -1 3303821056
0.384615391

0.33333333333333331 -1 12297829382473033728
0.33333333333333331

0.66666666666666663 0 12297829382473033728
0.66666666666666663

1 1 9223372036854775808
1

1.3333333333333333 1 12297829382473033728
1.3333333333333333

1.6666666666666667 1 15372286728091293696
1.6666666666666667

0.16666666666666666 -2 12297829382473033728
0.16666666666666666

0.33333333333333331 -1 12297829382473033728
0.33333333333333331

0.5 0 9223372036854775808
0.5

0.66666666666666663 0 12297829382473033728
0.66666666666666663

0.83333333333333337 0 15372286728091293696
0.83333333333333337

0.14285714285714285 -2 10540996613548314624
0.14285714285714285

0.2857142857142857 -1 10540996613548314624
0.2857142857142857

0.42857142857142855 -1 15811494920322471936
0.42857142857142855

0.5714285714285714 0 10540996613548314624
0.5714285714285714

0.7142857142857143 0 13176245766935394304
0.7142857142857143

0.1111111111111111 -3 16397105843297378304
0.1111111111111111

0.22222222222222221 -2 16397105843297378304
0.22222222222222221

0.33333333333333331 -1 12297829382473033728
0.33333333333333331

0.44444444444444442 -1 16397105843297378304
0.44444444444444442

0.55555555555555558 0 10248191152060862464
0.55555555555555558

0.090909090909090912 -3 13415813871788765184
0.090909090909090912

0.18181818181818182 -2 13415813871788765184
0.18181818181818182

0.27272727272727271 -1 10061860403841572864
0.27272727272727271

0.36363636363636365 -1 13415813871788765184
0.36363636363636365

0.45454545454545453 -1 16769767339735955456
0.45454545454545453

0.076923076923076927 -3 11351842506898186240
0.076923076923076927

0.15384615384615385 -2 11351842506898186240
0.15384615384615385

0.23076923076923078 -2 17027763760347279360
0.23076923076923078

0.30769230769230771 -1 11351842506898186240
0.30769230769230771

0.38461538461538464 -1 14189803133622732800
0.38461538461538464