ieee754.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // IEEE754 conversions based on https://github.com/feross/ieee754
  2. var global = require('../internals/global');
  3. var Array = global.Array;
  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 = 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 -- NaN check
  20. if (number != number || number === Infinity) {
  21. // eslint-disable-next-line no-self-compare -- NaN check
  22. mantissa = number != number ? 1 : 0;
  23. exponent = eMax;
  24. } else {
  25. exponent = floor(log(number) / LN2);
  26. c = pow(2, -exponent);
  27. if (number * c < 1) {
  28. exponent--;
  29. c *= 2;
  30. }
  31. if (exponent + eBias >= 1) {
  32. number += rt / c;
  33. } else {
  34. number += rt * pow(2, 1 - eBias);
  35. }
  36. if (number * c >= 2) {
  37. exponent++;
  38. c /= 2;
  39. }
  40. if (exponent + eBias >= eMax) {
  41. mantissa = 0;
  42. exponent = eMax;
  43. } else if (exponent + eBias >= 1) {
  44. mantissa = (number * c - 1) * pow(2, mantissaLength);
  45. exponent = exponent + eBias;
  46. } else {
  47. mantissa = number * pow(2, eBias - 1) * pow(2, mantissaLength);
  48. exponent = 0;
  49. }
  50. }
  51. while (mantissaLength >= 8) {
  52. buffer[index++] = mantissa & 255;
  53. mantissa /= 256;
  54. mantissaLength -= 8;
  55. }
  56. exponent = exponent << mantissaLength | mantissa;
  57. exponentLength += mantissaLength;
  58. while (exponentLength > 0) {
  59. buffer[index++] = exponent & 255;
  60. exponent /= 256;
  61. exponentLength -= 8;
  62. }
  63. buffer[--index] |= sign * 128;
  64. return buffer;
  65. };
  66. var unpack = function (buffer, mantissaLength) {
  67. var bytes = buffer.length;
  68. var exponentLength = bytes * 8 - mantissaLength - 1;
  69. var eMax = (1 << exponentLength) - 1;
  70. var eBias = eMax >> 1;
  71. var nBits = exponentLength - 7;
  72. var index = bytes - 1;
  73. var sign = buffer[index--];
  74. var exponent = sign & 127;
  75. var mantissa;
  76. sign >>= 7;
  77. while (nBits > 0) {
  78. exponent = exponent * 256 + buffer[index--];
  79. nBits -= 8;
  80. }
  81. mantissa = exponent & (1 << -nBits) - 1;
  82. exponent >>= -nBits;
  83. nBits += mantissaLength;
  84. while (nBits > 0) {
  85. mantissa = mantissa * 256 + buffer[index--];
  86. nBits -= 8;
  87. }
  88. if (exponent === 0) {
  89. exponent = 1 - eBias;
  90. } else if (exponent === eMax) {
  91. return mantissa ? NaN : sign ? -Infinity : Infinity;
  92. } else {
  93. mantissa = mantissa + pow(2, mantissaLength);
  94. exponent = exponent - eBias;
  95. } return (sign ? -1 : 1) * mantissa * pow(2, exponent - mantissaLength);
  96. };
  97. module.exports = {
  98. pack: pack,
  99. unpack: unpack
  100. };