fork download
  1. #include <iostream>
  2. #include <math.h>
  3. using namespace std;
  4.  
  5. struct Vec4Ni10w2;
  6.  
  7. struct Vec4f32
  8. {
  9. float x, y, z, w;
  10.  
  11. Vec4f32(float x, float y, float z, float w) :
  12. x(x), y(y), z(z), w(w)
  13. {
  14. }
  15.  
  16. Vec4f32(const Vec4Ni10w2 &v);
  17. };
  18.  
  19. struct Vec4Ni10w2
  20. {
  21. int x : 10;
  22. int y : 10;
  23. int z : 10;
  24. int w : 2;
  25.  
  26. Vec4Ni10w2(const Vec4f32 &v) :
  27. x(round(511 * v.x)), y(round(511 * v.y)), z(round(511 * v.z)), w(round(v.w))
  28. {
  29. }
  30. };
  31.  
  32. Vec4f32::Vec4f32(const Vec4Ni10w2 &v) :
  33. x((float)v.x / 511), y((float)v.y / 511), z((float)v.z / 511), w((float)v.w)
  34. {
  35. }
  36.  
  37. ostream& operator <<(ostream& out, const Vec4f32 &v)
  38. {
  39. return out << "(" << v.x << ", " << v.y << ", " << v.z << ", " << v.w << ")";
  40. }
  41.  
  42. ostream& operator <<(ostream& out, const Vec4Ni10w2 &v)
  43. {
  44. return out << "(" << v.x << ", " << v.y << ", " << v.z << ", " << v.w << ")";
  45. }
  46.  
  47. int main() {
  48. static_assert(sizeof(Vec4Ni10w2) == 4, "неверный размер Vec4Ni10w2");
  49.  
  50. Vec4f32 orig(0.2, -0.4, 0.6, -0.8);
  51. cout << "Исходный float32-вектор: " << orig << endl;
  52.  
  53. Vec4Ni10w2 denorm(orig);
  54. cout << "Денормализованный в INT_10_10_10_2: " << denorm << endl;
  55.  
  56. Vec4f32 back(denorm);
  57. cout << "Преобразованный назад во float32: " << back << endl;
  58.  
  59. return 0;
  60. }
Success #stdin #stdout 0s 4496KB
stdin
Standard input is empty
stdout
Исходный float32-вектор: (0.2, -0.4, 0.6, -0.8)
Денормализованный в INT_10_10_10_2: (102, -204, 307, -1)
Преобразованный назад во float32: (0.199609, -0.399217, 0.600783, -1)