ieee754.js 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. // IEEE754 conversions based on https://github.com/feross/ieee754
  2. // eslint-disable-next-line no-shadow-restricted-names
  3. var Infinity = 1 / 0;
  4. var abs = Math.abs;
  5. var pow = Math.pow;
  6. var floor = Math.floor;
  7. var log = Math.log;
  8. var LN2 = Math.LN2;
  9. var pack = function (number, mantissaLength, bytes) {
  10. var buffer = new Array(bytes);
  11. var exponentLength = bytes * 8 - mantissaLength - 1;
  12. var eMax = (1 << exponentLength) - 1;
  13. var eBias = eMax >> 1;
  14. var rt = mantissaLength === 23 ? pow(2, -24) - pow(2, -77) : 0;
  15. var sign = number < 0 || number === 0 && 1 / number < 0 ? 1 : 0;
  16. var index = 0;
  17. var exponent, mantissa, c;
  18. number = abs(number);
  19. // eslint-disable-next-line no-self-compare
  20. if (number != number || number === Infinity) {
  21. // eslint-disable-next-line no-self-compare
  22. mantissa = number != number ? 1 : 0;
  23. exponent = eMax;
  24. } else {
  25. exponent = floor(log(number) / LN2);
  26. if (number * (c = pow(2, -exponent)) < 1) {
  27. exponent--;
  28. c *= 2;
  29. }
  30. if (exponent + eBias >= 1) {
  31. number += rt / c;
  32. } else {
  33. number += rt * pow(2, 1 - eBias);
  34. }
  35. if (number * c >= 2) {
  36. exponent++;
  37. c /= 2;
  38. }
  39. if (exponent + eBias >= eMax) {
  40. mantissa = 0;
  41. exponent = eMax;
  42. } else if (exponent + eBias >= 1) {
  43. mantissa = (number * c - 1) * pow(2, mantissaLength);
  44. exponent = exponent + eBias;
  45. } else {
  46. mantissa = number * pow(2, eBias - 1) * pow(2, mantissaLength);
  47. exponent = 0;
  48. }
  49. }
  50. for (; mantissaLength >= 8; buffer[index++] = mantissa & 255, mantissa /= 256, mantissaLength -= 8);
  51. exponent = exponent << mantissaLength | mantissa;
  52. exponentLength += mantissaLength;
  53. for (; exponentLength > 0; buffer[index++] = exponent & 255, exponent /= 256, exponentLength -= 8);
  54. buffer[--index] |= sign * 128;
  55. return buffer;
  56. };
  57. var unpack = function (buffer, mantissaLength) {
  58. var bytes = buffer.length;
  59. var exponentLength = bytes * 8 - mantissaLength - 1;
  60. var eMax = (1 << exponentLength) - 1;
  61. var eBias = eMax >> 1;
  62. var nBits = exponentLength - 7;
  63. var index = bytes - 1;
  64. var sign = buffer[index--];
  65. var exponent = sign & 127;
  66. var mantissa;
  67. sign >>= 7;
  68. for (; nBits > 0; exponent = exponent * 256 + buffer[index], index--, nBits -= 8);
  69. mantissa = exponent & (1 << -nBits) - 1;
  70. exponent >>= -nBits;
  71. nBits += mantissaLength;
  72. for (; nBits > 0; mantissa = mantissa * 256 + buffer[index], index--, nBits -= 8);
  73. if (exponent === 0) {
  74. exponent = 1 - eBias;
  75. } else if (exponent === eMax) {
  76. return mantissa ? NaN : sign ? -Infinity : Infinity;
  77. } else {
  78. mantissa = mantissa + pow(2, mantissaLength);
  79. exponent = exponent - eBias;
  80. } return (sign ? -1 : 1) * mantissa * pow(2, exponent - mantissaLength);
  81. };
  82. module.exports = {
  83. pack: pack,
  84. unpack: unpack
  85. };