Advertisement
pasholnahuy

Untitled

Dec 15th, 2023
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.98 KB | None | 0 0
  1. #include <stdint.h>
  2.  
  3. typedef uint16_t Float16T;
  4.  
  5. enum {
  6. FRAC_MASK = (1 << 10) - 1,
  7. EXP_MASK = ((1 << 5) - 1) << 10,
  8. SIGN_MASK = 1 << 15,
  9. FRAC_WIDTH = 10,
  10. FIXED_EXP = 24,
  11. EXP_WIDTH = 5,
  12. NAN = EXP_MASK + FRAC_MASK,
  13. CONST24 = 24
  14. };
  15.  
  16. uint16_t is_nan(Float16T x) {
  17. if ((x & EXP_MASK) == EXP_MASK && (x & FRAC_MASK) != 0) {
  18. return 1;
  19. }
  20. return 0;
  21. }
  22.  
  23. uint16_t is_inf(Float16T x) {
  24. if ((x & EXP_MASK) == EXP_MASK && (x & FRAC_MASK) == 0) {
  25. return 1;
  26. }
  27. return 0;
  28. }
  29.  
  30. int64_t cast_fp16_to_fixed(Float16T x) {
  31. int64_t res;
  32. if (x & EXP_MASK) {
  33. res = (int64_t)((1 << FRAC_WIDTH) | (x & FRAC_MASK)) << (((x & EXP_MASK) >> FRAC_WIDTH) - 1);
  34. } else {
  35. res = x & FRAC_MASK;
  36. }
  37. if (x & SIGN_MASK) {
  38. res = -res;
  39. }
  40. return res;
  41. }
  42.  
  43. Float16T cast_fixed_to_fp16(int64_t x) {
  44. int u = 0;
  45. if (x < 0) {
  46. x = -x;
  47. u = 1;
  48. }
  49. if (x <= ((1 << FRAC_WIDTH) | FRAC_MASK)) {
  50. if (u) {
  51. return SIGN_MASK | x;
  52. }
  53. return x;
  54. }
  55.  
  56. int exp = 1;
  57. while (x >= (1 << (FRAC_WIDTH + 2))) {
  58. x = x >> 1;
  59. ++exp;
  60. }
  61. ++x;
  62. while (x >= 1 << (FRAC_WIDTH + 1)) {
  63. x = x >> 1;
  64. ++exp;
  65. }
  66. if (exp >= (1 << EXP_WIDTH) - 1) {
  67. if (u) {
  68. return EXP_MASK | SIGN_MASK;
  69. }
  70. return EXP_MASK;
  71. }
  72. if (u) {
  73. return SIGN_MASK | (exp << FRAC_WIDTH) | (x & FRAC_MASK);
  74. }
  75. return (exp << FRAC_WIDTH) | (x & FRAC_MASK);
  76. }
  77.  
  78. uint16_t fp16_mul2(uint16_t x) {
  79. if (is_nan(x) || is_inf(x)) {
  80. return x;
  81. }
  82. return cast_fixed_to_fp16(cast_fp16_to_fixed(x) << 1);
  83. }
  84.  
  85. uint16_t fp16_div2(uint16_t x) {
  86. if (is_nan(x) || is_inf(x)) {
  87. return x;
  88. }
  89. return cast_fixed_to_fp16(cast_fp16_to_fixed(x) >> 1);
  90. }
  91.  
  92. uint16_t fp16_neg(uint16_t x) { return x ^ SIGN_MASK; }
  93.  
  94. uint16_t fp16_add(uint16_t x, uint16_t y) {
  95. if ((is_nan(x) || is_inf(x)) || (is_inf(x) && is_inf(y) && (x ^ y) != 0)) {
  96. return NAN;
  97. }
  98. if (is_inf(x) || is_inf(y)) {
  99. return x;
  100. }
  101. return cast_fixed_to_fp16(cast_fp16_to_fixed(x) + cast_fp16_to_fixed(y));
  102. }
  103.  
  104. int fp16_cmp(uint16_t x, uint16_t y) {
  105. if (is_inf(x) && is_inf(y)) {
  106. if (x == y) {
  107. return 0;
  108. }
  109. if (x & SIGN_MASK) {
  110. return 1;
  111. }
  112. return -1;
  113. }
  114. if (is_inf(x) && !is_inf(y)) {
  115. if (x & SIGN_MASK) {
  116. return -1;
  117. }
  118. return 1;
  119. }
  120. if (!is_inf(x) && is_inf(y)) {
  121. if (y & SIGN_MASK) {
  122. return 1;
  123. }
  124. return -1;
  125. }
  126. if (cast_fp16_to_fixed(x) < cast_fp16_to_fixed(y)) {
  127. return -1;
  128. }
  129. if (cast_fp16_to_fixed(x) == cast_fp16_to_fixed(y)) {
  130. return 0;
  131. }
  132. return 1;
  133. }
  134.  
  135. uint16_t fp16_cast(unsigned int x) { return cast_fixed_to_fp16((int64_t)x << CONST24); }
  136.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement