/src/FreeImage/Source/OpenEXR/IlmImf/ImfRational.cpp

https://bitbucket.org/cabalistic/ogredeps/ · C++ · 125 lines · 66 code · 18 blank · 41 comment · 6 complexity · 46397aca5625a208406db9866c966b8c MD5 · raw file

  1. ///////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2006, Industrial Light & Magic, a division of Lucas
  4. // Digital Ltd. LLC
  5. //
  6. // All rights reserved.
  7. //
  8. // Redistribution and use in source and binary forms, with or without
  9. // modification, are permitted provided that the following conditions are
  10. // met:
  11. // * Redistributions of source code must retain the above copyright
  12. // notice, this list of conditions and the following disclaimer.
  13. // * Redistributions in binary form must reproduce the above
  14. // copyright notice, this list of conditions and the following disclaimer
  15. // in the documentation and/or other materials provided with the
  16. // distribution.
  17. // * Neither the name of Industrial Light & Magic nor the names of
  18. // its contributors may be used to endorse or promote products derived
  19. // from this software without specific prior written permission.
  20. //
  21. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  24. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  25. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  26. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  27. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  28. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  29. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  31. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32. //
  33. ///////////////////////////////////////////////////////////////////////////
  34. //-----------------------------------------------------------------------------
  35. //
  36. // Rational numbers
  37. //
  38. // The double-to-Rational conversion code below
  39. // was contributed to OpenEXR by Greg Ward.
  40. //
  41. //-----------------------------------------------------------------------------
  42. #include <ImfRational.h>
  43. #include <cmath>
  44. using namespace std;
  45. namespace Imf {
  46. namespace {
  47. double
  48. frac (double x, double e)
  49. {
  50. return x - floor (x + e);
  51. }
  52. double
  53. square (double x)
  54. {
  55. return x * x;
  56. }
  57. double
  58. denom (double x, double e)
  59. {
  60. if (e > frac (x, e))
  61. {
  62. return 1;
  63. }
  64. else
  65. {
  66. double r = frac (1 / x, e);
  67. if (e > r)
  68. {
  69. return floor (1 / x + e);
  70. }
  71. else
  72. {
  73. return denom (frac (1 / r, e), e / square (x * r)) +
  74. floor (1 / x + e) * denom (frac (1 / x, e), e / square (x));
  75. }
  76. }
  77. }
  78. } // namespace
  79. Rational::Rational (double x)
  80. {
  81. int sign;
  82. if (x >= 0)
  83. {
  84. sign = 1; // positive
  85. }
  86. else if (x < 0)
  87. {
  88. sign = -1; // negative
  89. x = -x;
  90. }
  91. else
  92. {
  93. n = 0; // NaN
  94. d = 0;
  95. return;
  96. }
  97. if (x >= (1U << 31) - 0.5)
  98. {
  99. n = sign; // infinity
  100. d = 0;
  101. return;
  102. }
  103. double e = (x < 1? 1: x) / (1U << 30);
  104. d = (unsigned int) denom (x, e);
  105. n = sign * (int) floor (x * d + 0.5);
  106. }
  107. } // namespace Imf