valueToFloat32Bytes.js 1.6 KB

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