ieee754.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // IEEE754 conversions based on https://github.com/feross/ieee754
  2. var $Array = Array;
  3. var abs = Math.abs;
  4. var pow = Math.pow;
  5. var floor = Math.floor;
  6. var log = Math.log;
  7. var LN2 = Math.LN2;
  8. var pack = function (number, mantissaLength, bytes) {
  9. var buffer = $Array(bytes);
  10. var exponentLength = bytes * 8 - mantissaLength - 1;
  11. var eMax = (1 << exponentLength) - 1;
  12. var eBias = eMax >> 1;
  13. var rt = mantissaLength === 23 ? pow(2, -24) - pow(2, -77) : 0;
  14. var sign = number < 0 || number === 0 && 1 / number < 0 ? 1 : 0;
  15. var index = 0;
  16. var exponent, mantissa, c;
  17. number = abs(number);
  18. // eslint-disable-next-line no-self-compare -- NaN check
  19. if (number != number || number === Infinity) {
  20. // eslint-disable-next-line no-self-compare -- NaN check
  21. mantissa = number != number ? 1 : 0;
  22. exponent = eMax;
  23. } else {
  24. exponent = floor(log(number) / LN2);
  25. c = pow(2, -exponent);
  26. if (number * c < 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. while (mantissaLength >= 8) {
  51. buffer[index++] = mantissa & 255;
  52. mantissa /= 256;
  53. mantissaLength -= 8;
  54. }
  55. exponent = exponent << mantissaLength | mantissa;
  56. exponentLength += mantissaLength;
  57. while (exponentLength > 0) {
  58. buffer[index++] = exponent & 255;
  59. exponent /= 256;
  60. exponentLength -= 8;
  61. }
  62. buffer[--index] |= sign * 128;
  63. return buffer;
  64. };
  65. var unpack = function (buffer, mantissaLength) {
  66. var bytes = buffer.length;
  67. var exponentLength = bytes * 8 - mantissaLength - 1;
  68. var eMax = (1 << exponentLength) - 1;
  69. var eBias = eMax >> 1;
  70. var nBits = exponentLength - 7;
  71. var index = bytes - 1;
  72. var sign = buffer[index--];
  73. var exponent = sign & 127;
  74. var mantissa;
  75. sign >>= 7;
  76. while (nBits > 0) {
  77. exponent = exponent * 256 + buffer[index--];
  78. nBits -= 8;
  79. }
  80. mantissa = exponent & (1 << -nBits) - 1;
  81. exponent >>= -nBits;
  82. nBits += mantissaLength;
  83. while (nBits > 0) {
  84. mantissa = mantissa * 256 + buffer[index--];
  85. nBits -= 8;
  86. }
  87. if (exponent === 0) {
  88. exponent = 1 - eBias;
  89. } else if (exponent === eMax) {
  90. return mantissa ? NaN : sign ? -Infinity : Infinity;
  91. } else {
  92. mantissa = mantissa + pow(2, mantissaLength);
  93. exponent = exponent - eBias;
  94. } return (sign ? -1 : 1) * mantissa * pow(2, exponent - mantissaLength);
  95. };
  96. module.exports = {
  97. pack: pack,
  98. unpack: unpack
  99. };