valueToFloat32Bytes.js 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. 'use strict';
  2. var $abs = require('math-intrinsics/abs');
  3. var $floor = require('math-intrinsics/floor');
  4. var $pow = require('math-intrinsics/pow');
  5. var isFinite = require('math-intrinsics/isFinite');
  6. var isNaN = require('math-intrinsics/isNaN');
  7. var isNegativeZero = require('math-intrinsics/isNegativeZero');
  8. var maxFiniteFloat32 = 3.4028234663852886e+38; // roughly 2 ** 128 - 1
  9. module.exports = function valueToFloat32Bytes(value, isLittleEndian) {
  10. if (isNaN(value)) {
  11. return isLittleEndian ? [0, 0, 192, 127] : [127, 192, 0, 0]; // hardcoded
  12. }
  13. var leastSig;
  14. if (value === 0) {
  15. leastSig = isNegativeZero(value) ? 0x80 : 0;
  16. return isLittleEndian ? [0, 0, 0, leastSig] : [leastSig, 0, 0, 0];
  17. }
  18. if ($abs(value) > maxFiniteFloat32 || !isFinite(value)) {
  19. leastSig = value < 0 ? 255 : 127;
  20. return isLittleEndian ? [0, 0, 128, leastSig] : [leastSig, 128, 0, 0];
  21. }
  22. var sign = value < 0 ? 1 : 0;
  23. value = $abs(value); // eslint-disable-line no-param-reassign
  24. var exponent = 0;
  25. while (value >= 2) {
  26. exponent += 1;
  27. value /= 2; // eslint-disable-line no-param-reassign
  28. }
  29. while (value < 1) {
  30. exponent -= 1;
  31. value *= 2; // eslint-disable-line no-param-reassign
  32. }
  33. var mantissa = value - 1;
  34. mantissa *= $pow(2, 23) + 0.5;
  35. mantissa = $floor(mantissa);
  36. exponent += 127;
  37. exponent <<= 23;
  38. var result = (sign << 31)
  39. | exponent
  40. | mantissa;
  41. var byte0 = result & 255;
  42. result >>= 8;
  43. var byte1 = result & 255;
  44. result >>= 8;
  45. var byte2 = result & 255;
  46. result >>= 8;
  47. var byte3 = result & 255;
  48. if (isLittleEndian) {
  49. return [byte0, byte1, byte2, byte3];
  50. }
  51. return [byte3, byte2, byte1, byte0];
  52. };