PageRenderTime 38ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llcommon/is_approx_equal_fraction.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 79 lines | 26 code | 9 blank | 44 comment | 3 complexity | 4291aab442aeddf2ca44a40055bad366 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file is_approx_equal_fraction.h
  3. * @author Nat Goodspeed
  4. * @date 2009-01-28
  5. * @brief lltut.h uses is_approx_equal_fraction(). Moved to this header
  6. * file in llcommon so we can use lltut.h for llcommon tests without
  7. * making llcommon depend on llmath.
  8. *
  9. * $LicenseInfo:firstyear=2009&license=viewerlgpl$
  10. * Second Life Viewer Source Code
  11. * Copyright (C) 2010, Linden Research, Inc.
  12. *
  13. * This library is free software; you can redistribute it and/or
  14. * modify it under the terms of the GNU Lesser General Public
  15. * License as published by the Free Software Foundation;
  16. * version 2.1 of the License only.
  17. *
  18. * This library is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  21. * Lesser General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU Lesser General Public
  24. * License along with this library; if not, write to the Free Software
  25. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  26. *
  27. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  28. * $/LicenseInfo$
  29. */
  30. #if ! defined(LL_IS_APPROX_EQUAL_FRACTION_H)
  31. #define LL_IS_APPROX_EQUAL_FRACTION_H
  32. #include "lldefs.h"
  33. #include <cmath>
  34. /**
  35. * Originally llmath.h contained two complete implementations of
  36. * is_approx_equal_fraction(), with signatures as below, bodies identical save
  37. * where they specifically mentioned F32/F64. Unifying these into a template
  38. * makes sense -- but to preserve the compiler's overload-selection behavior,
  39. * we still wrap the template implementation with the specific overloaded
  40. * signatures.
  41. */
  42. template <typename FTYPE>
  43. inline BOOL is_approx_equal_fraction_impl(FTYPE x, FTYPE y, U32 frac_bits)
  44. {
  45. BOOL ret = TRUE;
  46. FTYPE diff = (FTYPE) fabs(x - y);
  47. S32 diffInt = (S32) diff;
  48. S32 diffFracTolerance = (S32) ((diff - (FTYPE) diffInt) * (1 << frac_bits));
  49. // if integer portion is not equal, not enough bits were used for packing
  50. // so error out since either the use case is not correct OR there is
  51. // an issue with pack/unpack. should fail in either case.
  52. // for decimal portion, make sure that the delta is no more than 1
  53. // based on the number of bits used for packing decimal portion.
  54. if (diffInt != 0 || diffFracTolerance > 1)
  55. {
  56. ret = FALSE;
  57. }
  58. return ret;
  59. }
  60. /// F32 flavor
  61. inline BOOL is_approx_equal_fraction(F32 x, F32 y, U32 frac_bits)
  62. {
  63. return is_approx_equal_fraction_impl<F32>(x, y, frac_bits);
  64. }
  65. /// F64 flavor
  66. inline BOOL is_approx_equal_fraction(F64 x, F64 y, U32 frac_bits)
  67. {
  68. return is_approx_equal_fraction_impl<F64>(x, y, frac_bits);
  69. }
  70. #endif /* ! defined(LL_IS_APPROX_EQUAL_FRACTION_H) */