_pack-ieee754.js 1.9KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. /* eslint no-bitwise: "off" */
  2. // Credit: https://github.com/paulmillr/es6-shim/
  3. "use strict";
  4. var abs = Math.abs
  5. , floor = Math.floor
  6. , log = Math.log
  7. , min = Math.min
  8. , pow = Math.pow
  9. , LN2 = Math.LN2
  10. , roundToEven;
  11. roundToEven = function (num) {
  12. var whole = floor(num), fraction = num - whole;
  13. if (fraction < 0.5) return whole;
  14. if (fraction > 0.5) return whole + 1;
  15. return whole % 2 ? whole + 1 : whole;
  16. };
  17. // eslint-disable-next-line max-statements
  18. module.exports = function (value, ebits, fbits) {
  19. var bias = (1 << (ebits - 1)) - 1, sign, e, fraction, i, bits, str, bytes;
  20. // Compute sign, exponent, fraction
  21. if (isNaN(value)) {
  22. // NaN
  23. // http://dev.w3.org/2006/webapi/WebIDL/#es-type-mapping
  24. e = (1 << ebits) - 1;
  25. fraction = pow(2, fbits - 1);
  26. sign = 0;
  27. } else if (value === Infinity || value === -Infinity) {
  28. e = (1 << ebits) - 1;
  29. fraction = 0;
  30. sign = value < 0 ? 1 : 0;
  31. } else if (value === 0) {
  32. e = 0;
  33. fraction = 0;
  34. sign = 1 / value === -Infinity ? 1 : 0;
  35. } else {
  36. sign = value < 0;
  37. value = abs(value);
  38. if (value >= pow(2, 1 - bias)) {
  39. e = min(floor(log(value) / LN2), 1023);
  40. fraction = roundToEven(value / pow(2, e) * pow(2, fbits));
  41. if (fraction / pow(2, fbits) >= 2) {
  42. e += 1;
  43. fraction = 1;
  44. }
  45. if (e > bias) {
  46. // Overflow
  47. e = (1 << ebits) - 1;
  48. fraction = 0;
  49. } else {
  50. // Normal
  51. e += bias;
  52. fraction -= pow(2, fbits);
  53. }
  54. } else {
  55. // Subnormal
  56. e = 0;
  57. fraction = roundToEven(value / pow(2, 1 - bias - fbits));
  58. }
  59. }
  60. // Pack sign, exponent, fraction
  61. bits = [];
  62. for (i = fbits; i; i -= 1) {
  63. bits.push(fraction % 2 ? 1 : 0);
  64. fraction = floor(fraction / 2);
  65. }
  66. for (i = ebits; i; i -= 1) {
  67. bits.push(e % 2 ? 1 : 0);
  68. e = floor(e / 2);
  69. }
  70. bits.push(sign ? 1 : 0);
  71. bits.reverse();
  72. str = bits.join("");
  73. // Bits to bytes
  74. bytes = [];
  75. while (str.length) {
  76. bytes.push(parseInt(str.substring(0, 8), 2));
  77. str = str.substring(8);
  78. }
  79. return bytes;
  80. };