選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

116 行
3.9 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the Do What The Fuck You Want To
  7. // Public License, Version 2, as published by Sam Hocevar. See
  8. // http://sam.zoy.org/projects/COPYING.WTFPL for more details.
  9. //
  10. //
  11. // The Half class
  12. // --------------
  13. //
  14. #if !defined __LOL_HALF_H__
  15. #define __LOL_HALF_H__
  16. #include <cstdio>
  17. #include <stdint.h>
  18. namespace lol
  19. {
  20. class half
  21. {
  22. public:
  23. /* Constructors. Always inline so that the code can work in registers
  24. * instead of calling routines with the hidden "this" parameter. */
  25. inline half() { }
  26. inline half(int f) { *this = makefast(f); }
  27. inline half(float f) { *this = makefast(f); }
  28. inline half(double f) { *this = makefast(f); }
  29. inline int is_nan() const
  30. {
  31. return ((bits & 0x7c00u) == 0x7c00u) && (bits & 0x03ffu);
  32. }
  33. inline int is_finite() const
  34. {
  35. return (bits & 0x7c00u) != 0x7c00u;
  36. }
  37. inline int is_inf() const
  38. {
  39. return (uint16_t)(bits << 1) == (0x7c00u << 1);
  40. }
  41. inline int is_normal() const
  42. {
  43. return (is_finite() && (bits & 0x7c00u)) || ((bits & 0x7fffu) == 0);
  44. }
  45. /* Cast to other types -- always inline, see constructors */
  46. inline half &operator =(int f) { return *this = makefast(f); }
  47. inline half &operator =(float f) { return *this = makefast(f); }
  48. inline half &operator =(double f) { return *this = makefast(f); }
  49. inline operator int() const { return (int)tofloat(*this); }
  50. inline operator float() const { return tofloat(*this); }
  51. static float tofloat(half h);
  52. /* Array conversions */
  53. static size_t convert(half *dst, float const *src, size_t nelem);
  54. static size_t convert(float *dst, half const *src, size_t nelem);
  55. /* Operations */
  56. inline half operator -() { return makebits(bits ^ 0x8000u); }
  57. inline half &operator +=(float f) { return (*this = (half)(*this + f)); }
  58. inline half &operator -=(float f) { return (*this = (half)(*this - f)); }
  59. inline half &operator *=(float f) { return (*this = (half)(*this * f)); }
  60. inline half &operator /=(float f) { return (*this = (half)(*this / f)); }
  61. inline half &operator +=(half h) { return (*this = (half)(*this + h)); }
  62. inline half &operator -=(half h) { return (*this = (half)(*this - h)); }
  63. inline half &operator *=(half h) { return (*this = (half)(*this * h)); }
  64. inline half &operator /=(half h) { return (*this = (half)(*this / h)); }
  65. inline float operator +(float f) const { return (float)*this + f; }
  66. inline float operator -(float f) const { return (float)*this - f; }
  67. inline float operator *(float f) const { return (float)*this * f; }
  68. inline float operator /(float f) const { return (float)*this / f; }
  69. inline float operator +(half h) const { return (float)*this + (float)h; }
  70. inline float operator -(half h) const { return (float)*this - (float)h; }
  71. inline float operator *(half h) const { return (float)*this * (float)h; }
  72. inline float operator /(half h) const { return (float)*this / (float)h; }
  73. /* Factories */
  74. static half makefast(float f);
  75. static half makeaccurate(float f);
  76. static inline half makebits(uint16_t x)
  77. {
  78. half ret;
  79. ret.bits = x;
  80. return ret;
  81. }
  82. /* Internal representation */
  83. uint16_t bits;
  84. };
  85. inline float &operator +=(float &f, half h) { return f += (float)h; }
  86. inline float &operator -=(float &f, half h) { return f -= (float)h; }
  87. inline float &operator *=(float &f, half h) { return f *= (float)h; }
  88. inline float &operator /=(float &f, half h) { return f /= (float)h; }
  89. inline float operator +(float f, half h) { return f + (float)h; }
  90. inline float operator -(float f, half h) { return f - (float)h; }
  91. inline float operator *(float f, half h) { return f * (float)h; }
  92. inline float operator /(float f, half h) { return f / (float)h; }
  93. } /* namespace lol */
  94. #endif // __LOL_HALF_H__