Advertisement
hxrussia

Arbitrary-precision floating-point numbers in JScript

Feb 19th, 2016
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Array.generate = function (count, value) {
  2.     var res = new Array(count);
  3.     for (var i = 0; i < count; i++)
  4.         res[i] = value;
  5.     return res;
  6. }
  7.  
  8. Array.prototype.map = function (func) {
  9.     var res = new Array(this.length);
  10.     for (var i = 0; i < this.length; i++)
  11.         res[i] = func(this[i]);
  12.     return res;
  13. }
  14.  
  15. Array.prototype.allAre = function (value) {
  16.     for (var i = 0; i < this.length; i++)
  17.         if (this[i] != value)
  18.             return false;
  19.     return true;
  20. }
  21.  
  22. Array.prototype.anyIs = function (value) {
  23.     for (var i = 0; i < this.length; i++)
  24.         if (this[i] == value)
  25.             return true;
  26.     return false;
  27. }
  28.  
  29.  
  30. function UnsignedInt(bits) {
  31.     this._bits = bits.slice();
  32.     this._popZeros();
  33. }
  34.  
  35. UnsignedInt._Base = 2;
  36.    
  37. UnsignedInt.prototype._popZeros = function () {
  38.     while (this._bits[this._bits.length - 1] == 0)
  39.         this._bits.pop();
  40. };
  41.  
  42. UnsignedInt.add = function (a, b) {
  43.     var a_bits = a._bits;
  44.     var b_bits = b._bits;
  45.     var bits = new Array(Math.max(a_bits.length, b_bits.length) + 1);
  46.     for (var i = 0; i < bits.length; i++)
  47.         bits[i] = 0;
  48.     for (var i = 0; i < bits.length; i++) {
  49.         if (i < a_bits.length)
  50.             bits[i] += a_bits[i];
  51.         if (i < b_bits.length)
  52.             bits[i] += b_bits[i];
  53.         if (bits[i] >= UnsignedInt._Base) {
  54.             bits[i + 1]++;
  55.             bits[i] -= UnsignedInt._Base;
  56.         }
  57.     }
  58.     return new UnsignedInt(bits);
  59. };
  60.  
  61. UnsignedInt.sub = function (a, b) {
  62.     if (UnsignedInt.compare(a, b) < 0)
  63.         throw new Error("Can't subtract an unsigned number from a lesser unsigned number");
  64.     var a_bits = a._bits;
  65.     var b_bits = b._bits;
  66.     var bits = new Array(a_bits.length);
  67.     for (var i = 0; i < bits.length; i++)
  68.         bits[i] = 0;
  69.     for (var i = 0; i < bits.length; i++) {
  70.         bits[i] += a_bits[i];
  71.         if (i < b_bits.length)
  72.             bits[i] -= b_bits[i];
  73.         if (bits[i] < 0) {
  74.             bits[i + 1]--;
  75.             bits[i] += UnsignedInt._Base;
  76.         }
  77.     }
  78.     return new UnsignedInt(bits);
  79. };
  80.  
  81. UnsignedInt.mul = function (a, b) {
  82.     var a_bits = a._bits;
  83.     var b_bits = b._bits;
  84.     var bits = new Array(a_bits.length + b_bits.length);
  85.     for (var i = 0; i < bits.length; i++)
  86.         bits[i] = 0;
  87.     for (var i = 0; i < a_bits.length; i++)
  88.         for (var j = 0; j < b_bits.length; j++) {
  89.             var k = i + j;
  90.             bits[k] += a_bits[i] * b_bits[j];
  91.             if (bits[k] >= UnsignedInt._Base) {
  92.                 bits[k + 1] += Math.floor(bits[k] / UnsignedInt._Base);
  93.                 bits[k] %= UnsignedInt._Base;
  94.             }
  95.         }
  96.     return new UnsignedInt(bits);
  97. };
  98.    
  99. UnsignedInt.fromBits = function (bits) {
  100.     return new UnsignedInt(bits);
  101. };
  102.    
  103. UnsignedInt.prototype.toBits = function (count) {
  104.     var bits = this._bits.slice();
  105.     if (count !== undefined) {
  106.         while (bits.length < count)
  107.             bits.push(0);
  108.     }
  109.     return bits;
  110. };
  111.  
  112. UnsignedInt.prototype.shiftLeftBy = function (positions) {
  113.     return new UnsignedInt(Array.generate(positions, 0).concat(this._bits));
  114. }
  115.  
  116. UnsignedInt.prototype.shiftRightBy = function (positions) {
  117.     return new UnsignedInt(this._bits.slice(positions));
  118. }
  119.  
  120. UnsignedInt.compare = function (a, b) {
  121.     var a_bits = a._bits;
  122.     var b_bits = b._bits;
  123.     if (a_bits.length != b_bits.length)
  124.         return (a_bits.length < b_bits.length) ? -1 : 1;
  125.     for (var i = a_bits.length - 1; i != -1; i--)
  126.         if (a_bits[i] != b_bits[i])
  127.             return (a_bits[i] < b_bits[i]) ? -1 : 1;
  128.     return 0;
  129. }
  130.  
  131. UnsignedInt.prototype.isZero = function () {
  132.     return this._bits.length == 0;
  133. }
  134.  
  135. UnsignedInt.Zero = new UnsignedInt([]);
  136. UnsignedInt.One = new UnsignedInt([1]);
  137.  
  138.  
  139. function Float(fraction, exponent, sign) {
  140.     this._fraction = fraction;
  141.     this._exponent = exponent;
  142.     this._sign = sign;
  143. }
  144.  
  145. Float._ExponentBits = 8;
  146. Float._FractionBits = 23;
  147.  
  148. Float.prototype.isPositive = function () {
  149.     return this._sign == 0;
  150. };
  151.  
  152. Float.prototype.isNegative = function () {
  153.     return !this.isPositive();
  154. };
  155.  
  156. Float.prototype.negate = function () {
  157.     if (this.isNaN())
  158.         return this;
  159.        
  160.     return new Float(this._fraction, this._exponent, this._sign ? 0 : 1);
  161. }
  162.  
  163. Float.prototype.abs = function () {
  164.     if (this.isNaN())
  165.         return this;
  166.        
  167.     return new Float(this._fraction, this._exponent, 0);
  168. }
  169.  
  170. Float.compare = function (a, b) {
  171.     if (a._sign != b._sign)
  172.         return a.sign == 1 ? -1 : 1;
  173.     var res = UnsignedInt.compare(a._exponent, b._exponent);
  174.     if (res)
  175.         return res;
  176.     return UnsignedInt.compare(a._fraction, b._fraction);
  177. }
  178.  
  179. Float._FractionImplicitPart = new UnsignedInt(Array.generate(Float._FractionBits, 0).concat([1]));
  180. Float._ExponentZeroLevel = new UnsignedInt(Array.generate(Float._ExponentBits - 1, 1));
  181.  
  182. Float.prototype._getExplicitFractionOfNonZeroNumber = function () {
  183.     if (this._exponent.isZero()) // Denormalized number
  184.         return this._fraction;
  185.     return UnsignedInt.add(Float._FractionImplicitPart, this._fraction);
  186. }
  187.  
  188. Float.prototype._getExplicitExponentOfNonZeroNumber = function () {
  189.     if (this._exponent.isZero()) // Denormalized number
  190.         return UnsignedInt.One;
  191.     return this._exponent;
  192. }
  193.  
  194. Float._ShiftedFractionImplicitPart = Float._FractionImplicitPart.shiftLeftBy(1);
  195.  
  196. Float._addNonZeroNumbers = function (a, b) {
  197.     var a_fraction = a._getExplicitFractionOfNonZeroNumber();
  198.     var b_fraction = b._getExplicitFractionOfNonZeroNumber();
  199.     var a_exponent = a._getExplicitExponentOfNonZeroNumber();
  200.     var b_exponent = b._getExplicitExponentOfNonZeroNumber();
  201.     while (UnsignedInt.compare(a_exponent, b_exponent) < 0) {
  202.         a_exponent = UnsignedInt.add(a_exponent, UnsignedInt.One);
  203.         a_fraction = a_fraction.shiftRightBy(1);
  204.     }
  205.     while (UnsignedInt.compare(a_exponent, b_exponent) > 0) {
  206.         b_exponent = UnsignedInt.add(b_exponent, UnsignedInt.One);
  207.         b_fraction = b_fraction.shiftRightBy(1);
  208.     }
  209.    
  210.     var res_fraction = UnsignedInt.add(a_fraction, b_fraction);
  211.     var res_exponent = a_exponent;
  212.     if (UnsignedInt.compare(res_fraction, Float._ShiftedFractionImplicitPart) >= 0) {
  213.         res_exponent = UnsignedInt.add(res_exponent, UnsignedInt.One);
  214.         res_fraction = res_fraction.shiftRightBy(1);
  215.     }
  216.     // Check overflow
  217.     if (UnsignedInt.compare(res_exponent, Float._ExponentOfInfinity) >= 0)
  218.         return a._sign ? Float.NegativeInfinity : Float.PositiveInfinity;
  219.     // Check if the result is denormalized
  220.     if (UnsignedInt.compare(res_exponent, UnsignedInt.One) == 0 && UnsignedInt.compare(res_fraction, Float._FractionImplicitPart) < 0)
  221.         return new Float(res_fraction, UnsignedInt.Zero, a._sign);
  222.     return new Float(UnsignedInt.sub(res_fraction, Float._FractionImplicitPart), res_exponent, a._sign);
  223. };
  224.  
  225. Float._subNonZeroNumbers = function (a, b) {
  226.     var a_fraction = a._getExplicitFractionOfNonZeroNumber();
  227.     var b_fraction = b._getExplicitFractionOfNonZeroNumber();
  228.     var a_exponent = a._getExplicitExponentOfNonZeroNumber();
  229.     var b_exponent = b._getExplicitExponentOfNonZeroNumber();
  230.     while (UnsignedInt.compare(a_exponent, b_exponent) < 0) {
  231.         a_exponent = UnsignedInt.add(a_exponent, UnsignedInt.One);
  232.         a_fraction = a_fraction.shiftRightBy(1);
  233.     }
  234.     while (UnsignedInt.compare(a_exponent, b_exponent) > 0) {
  235.         b_exponent = UnsignedInt.add(b_exponent, UnsignedInt.One);
  236.         b_fraction = b_fraction.shiftRightBy(1);
  237.     }
  238.    
  239.     var res_fraction = UnsignedInt.sub(a_fraction, b_fraction);
  240.     var res_exponent = a_exponent;
  241.     while (
  242.         UnsignedInt.compare(res_exponent, UnsignedInt.One) > 0 &&
  243.         UnsignedInt.compare(res_fraction, Float._FractionImplicitPart) < 0
  244.     ) {
  245.         res_exponent = UnsignedInt.sub(res_exponent, UnsignedInt.One);
  246.         res_fraction = res_fraction.shiftLeftBy(1);
  247.     }
  248.     // Check if the result is denormalized
  249.     if (UnsignedInt.compare(res_exponent, UnsignedInt.One) == 0 && UnsignedInt.compare(res_fraction, Float._FractionImplicitPart) < 0)
  250.         return new Float(res_fraction, UnsignedInt.Zero, a._sign);
  251.     return new Float(UnsignedInt.sub(res_fraction, Float._FractionImplicitPart), res_exponent, a._sign);
  252. };
  253.    
  254. Float.add = function (a, b) {
  255.     if (a.isNaN())
  256.         return a;
  257.     if (b.isNaN())
  258.         return b;
  259.        
  260.     if (a.isInfinity())
  261.         return (b.isInfinity() && a.isPositive() != b.isPositive()) ? Float.NaN : a;
  262.     if (b.isInfinity())
  263.         return b;
  264.        
  265.     if (a.isZero()) {
  266.         if (b.isZero())
  267.             return (a.isNegative() && b.isNegative()) ? a : Float.PositiveZero;
  268.         return b;
  269.     }
  270.     if (b.isZero())
  271.         return a;
  272.    
  273.     if (a.isPositive() != b.isPositive()) {
  274.         if (Float.compare(a.abs(), b.abs()) >= 0)
  275.             return Float._subNonZeroNumbers(a, b.negate());
  276.         else
  277.             return Float._subNonZeroNumbers(b.negate(), a).negate();
  278.     }
  279.     return Float._addNonZeroNumbers(a, b);
  280. };
  281.  
  282. Float.sub = function (a, b) {
  283.     if (a.isNaN())
  284.         return a;
  285.     if (b.isNaN())
  286.         return b;
  287.        
  288.     return Float.add(a, b.negate());
  289. }
  290.  
  291. Float._ExponentOneLevel = UnsignedInt.add(Float._ExponentZeroLevel, UnsignedInt.One);
  292. Float._FractionImplicitPartSquare = UnsignedInt.mul(Float._FractionImplicitPart, Float._FractionImplicitPart);
  293.  
  294. Float._mulNonZeroNumbers = function (a, b) {
  295.     var a_fraction = a._getExplicitFractionOfNonZeroNumber();
  296.     var b_fraction = b._getExplicitFractionOfNonZeroNumber();
  297.     var a_exponent = a._getExplicitExponentOfNonZeroNumber();
  298.     var b_exponent = b._getExplicitExponentOfNonZeroNumber();
  299.    
  300.     var res_exponent = UnsignedInt.add(a_exponent, b_exponent);
  301.     var res_fraction = UnsignedInt.mul(a_fraction, b_fraction);
  302.     while (
  303.         UnsignedInt.compare(res_exponent, Float._ExponentOneLevel) > 0 &&
  304.         UnsignedInt.compare(res_fraction, Float._FractionImplicitPartSquare) < 0
  305.     ) {
  306.         res_exponent = UnsignedInt.sub(res_exponent, UnsignedInt.One);
  307.         res_fraction = res_fraction.shiftLeftBy(1);
  308.     }
  309.     res_fraction = res_fraction.shiftRightBy(Float._FractionBits);
  310.     if (UnsignedInt.compare(res_fraction, Float._ShiftedFractionImplicitPart) >= 0) {
  311.         res_exponent = UnsignedInt.add(res_exponent, UnsignedInt.One);
  312.         res_fraction = res_fraction.shiftRightBy(1);
  313.     }
  314.     // Check if the result is denormalized
  315.     if (
  316.         UnsignedInt.compare(res_exponent, Float._ExponentZeroLevel) <= 0 || (
  317.             UnsignedInt.compare(res_exponent, Float._ExponentOneLevel) == 0 &&
  318.             UnsignedInt.compare(res_fraction, Float._FractionImplicitPart) < 0
  319.         )
  320.     ) {
  321.         while (UnsignedInt.compare(res_exponent, Float._ExponentZeroLevel) <= 0) {
  322.             res_exponent = UnsignedInt.add(res_exponent, UnsignedInt.One);
  323.             res_fraction = res_fraction.shiftRightBy(1);
  324.         }
  325.         return new Float(res_fraction, UnsignedInt.Zero, 0);
  326.     }
  327.     res_fraction = UnsignedInt.sub(res_fraction, Float._FractionImplicitPart);
  328.     res_exponent = UnsignedInt.sub(res_exponent, Float._ExponentZeroLevel);
  329.     return new Float(res_fraction, res_exponent, 0);
  330. };
  331.  
  332. Float.mul = function (a, b) {
  333.     if (a.isNaN())
  334.         return a;
  335.     if (b.isNaN())
  336.         return b;
  337.    
  338.     if (a.isNegative() && b.isNegative())
  339.         return Float.mul(a.negate(), b.negate());
  340.     if (a.isNegative())
  341.         return Float.mul(a.negate(), b).negate();
  342.     if (b.isNegative())
  343.         return Float.mul(a, b.negate()).negate();
  344.        
  345.     if (a.isInfinity())
  346.         return b.isZero() ? Float.NaN : Float.PositiveInfinity;
  347.     if (b.isInfinity())
  348.         return a.isZero() ? Float.NaN : Float.PositiveInfinity;
  349.        
  350.     if (a.isZero() || b.isZero())
  351.         return Float.PositiveZero;
  352.        
  353.     return Float._mulNonZeroNumbers(a, b);
  354. };
  355.  
  356. Float.Half = new Float(
  357.     new UnsignedInt(Array.generate(Float._FractionBits, 0)),
  358.     UnsignedInt.sub(Float._ExponentZeroLevel, UnsignedInt.One),
  359.     0
  360. );
  361.  
  362. Float._BinSearchIters = (1 << Float._ExponentBits) + Float._FractionBits + 10;
  363.  
  364. Float._divNonZeroNumbers = function (a, b) {
  365.     var l = Float.PositiveZero;
  366.     var r = Float.MaxValue;
  367.     for (var i = 0; i < Float._BinSearchIters; i++) {
  368.         var middle = Float.add(l, Float.mul(Float.sub(r, l), Float.Half));
  369.         if (Float.compare(Float.mul(middle, b), a) < 0)
  370.             l = middle;
  371.         else
  372.             r = middle;
  373.     }
  374.     return r;
  375. };
  376.  
  377. Float.div = function (a, b) {
  378.     if (a.isNaN())
  379.         return a;
  380.     if (b.isNaN())
  381.         return b;
  382.    
  383.     if (a.isNegative() && b.isNegative())
  384.         return Float.div(a.negate(), b.negate());
  385.     if (a.isNegative())
  386.         return Float.div(a.negate(), b).negate();
  387.     if (b.isNegative())
  388.         return Float.div(a, b.negate()).negate();
  389.        
  390.     if (a.isInfinity())
  391.         return b.isInfinity() ? Float.NaN : Float.PositiveInfinity;
  392.     if (b.isInfinity())
  393.         return Float.PositiveZero;
  394.        
  395.     if (a.isZero())
  396.         return Float.PositiveZero;
  397.     if (b.isZero())
  398.         return Float.PositiveInfinity;
  399.        
  400.     return Float._divNonZeroNumbers(a, b);
  401. };
  402.  
  403. Float.prototype._sqrtFromNonZeroNumber = function () {
  404.     var l = Float.PositiveZero;
  405.     var r = Float.MaxValue;
  406.     for (var i = 0; i < Float._BinSearchIters; i++) {
  407.         var middle = Float.add(l, Float.mul(Float.sub(r, l), Float.Half));
  408.         if (Float.compare(Float.mul(middle, middle), this) < 0)
  409.             l = middle;
  410.         else
  411.             r = middle;
  412.     }
  413.     return r;
  414. }
  415.  
  416. Float.prototype.sqrt = function () {
  417.     if (this.isNaN())
  418.         return this;
  419.    
  420.     if (this.isZero())
  421.         return Float.PositiveZero;
  422.        
  423.     if (this.isNegative())
  424.         return Float.NaN;
  425.    
  426.     if (this.isInfinity())
  427.         return Float.PositiveInfinity;
  428.    
  429.     return this._sqrtFromNonZeroNumber();
  430. }
  431.  
  432. Float._RowSummands = 64;
  433.  
  434. Float.prototype.sin = function () {
  435.     if (this.isNaN())
  436.         return this;
  437.    
  438.     if (this.isInfinity())
  439.         return Float.NaN;
  440.    
  441.     var res = this;
  442.     var numerator = this;
  443.     var denomFactor = Float.One;
  444.     var denom = Float.One;
  445.     for (var i = 0; i < Float._RowSummands; i++) {
  446.         numerator = Float.mul(Float.mul(numerator, this), this);
  447.         denomFactor = Float.add(denomFactor, Float.One);
  448.         denom = Float.mul(denom, denomFactor);
  449.         denomFactor = Float.add(denomFactor, Float.One);
  450.         denom = Float.mul(denom, denomFactor);
  451.         var summand = Float.div(numerator, denom);
  452.         if (i % 2 == 0)
  453.             summand = summand.negate();
  454.         res = Float.add(res, summand);
  455.     }
  456.     return res;
  457. }
  458.  
  459. Float.prototype.cos = function () {
  460.     if (this.isNaN())
  461.         return this;
  462.    
  463.     if (this.isInfinity())
  464.         return Float.NaN;
  465.    
  466.     var res = Float.One;
  467.     var numerator = Float.One;
  468.     var denomFactor = Float.PositiveZero;
  469.     var denom = Float.One;
  470.     for (var i = 0; i < Float._RowSummands; i++) {
  471.         numerator = Float.mul(Float.mul(numerator, this), this);
  472.         denomFactor = Float.add(denomFactor, Float.One);
  473.         denom = Float.mul(denom, denomFactor);
  474.         denomFactor = Float.add(denomFactor, Float.One);
  475.         denom = Float.mul(denom, denomFactor);
  476.         var summand = Float.div(numerator, denom);
  477.         if (i % 2 == 0)
  478.             summand = summand.negate();
  479.         res = Float.add(res, summand);
  480.     }
  481.     return res;
  482. }
  483.    
  484. Float.fromBits = function (bits) {
  485.     if (bits.length !== Float._ExponentBits + Float._FractionBits + 1)
  486.         throw new Error("Incorrect bits count in Float representation");
  487.     return new Float(
  488.         new UnsignedInt(bits.slice(0, Float._FractionBits)),
  489.         new UnsignedInt(bits.slice(Float._FractionBits, Float._FractionBits + Float._ExponentBits)),
  490.         bits[Float._FractionBits + Float._ExponentBits]
  491.     );
  492. };
  493.    
  494. Float.prototype.toBits = function () {
  495.     return this._fraction.toBits(Float._FractionBits).concat(this._exponent.toBits(Float._ExponentBits)).concat([this._sign]);
  496. };
  497.  
  498. Float.fromBinary = function (str) {
  499.     return Float.fromBits(str.replace(/\s/g, '').split('').reverse().map(function (bit) {
  500.         return +bit;
  501.     }));
  502. }
  503.  
  504. Float.prototype.toBinary = function (str) {
  505.     return (
  506.         this._sign + " " +
  507.         this._exponent.toBits(Float._ExponentBits).reverse().join("") + " " +
  508.         this._fraction.toBits(Float._FractionBits).reverse().join("")
  509.     );
  510. }
  511.  
  512. Float._ExponentOfInfinity = new UnsignedInt(Array.generate(Float._ExponentBits, 1));
  513.  
  514. Float.prototype.isNaN = function () {
  515.     return !this._fraction.isZero() && UnsignedInt.compare(this._exponent, Float._ExponentOfInfinity) == 0;
  516. };
  517.    
  518. Float.NaN = new Float(
  519.     new UnsignedInt(Array.generate(Float._FractionBits, 1)),
  520.     Float._ExponentOfInfinity,
  521.     1
  522. );
  523.  
  524. Float.prototype.isInfinity = function () {
  525.     return this._fraction.isZero() && UnsignedInt.compare(this._exponent, Float._ExponentOfInfinity) == 0;
  526. };
  527.  
  528. Float.MaxValue = new Float(
  529.     new UnsignedInt(Array.generate(Float._FractionBits, 1)),
  530.     UnsignedInt.sub(Float._ExponentOfInfinity, UnsignedInt.One),
  531.     0
  532. );
  533.  
  534. Float.PositiveInfinity = new Float(
  535.     new UnsignedInt(Array.generate(Float._FractionBits, 0)),
  536.     Float._ExponentOfInfinity,
  537.     0
  538. );
  539. Float.NegativeInfinity = Float.PositiveInfinity.negate();
  540.  
  541. Float.prototype.isZero = function () {
  542.     return this._fraction.isZero() && this._exponent.isZero();
  543. }
  544.  
  545. Float.PositiveZero = new Float(
  546.     new UnsignedInt(Array.generate(Float._FractionBits, 0)),
  547.     new UnsignedInt(Array.generate(Float._ExponentBits, 0)),
  548.     0
  549. );
  550. Float.NegativeZero = Float.PositiveZero.negate();
  551.  
  552. Float.One = new Float(
  553.     new UnsignedInt(Array.generate(Float._FractionBits, 0)),
  554.     Float._ExponentZeroLevel,
  555.     0
  556. );
  557.  
  558. Float._DecimalBase = 10;
  559. Float._Digits = new Array(Float._DecimalBase);
  560. Float._Digits[0] = Float.PositiveZero;
  561. Float._Digits[1] = Float.One;
  562. for (var i = 2; i < Float._DecimalBase; i++)
  563.     Float._Digits[i] = Float.add(Float._Digits[i - 1], Float.One);
  564.  
  565. Float._Ten = Float.add(Float._Digits[Float._DecimalBase - 1], Float.One);
  566.  
  567. /*Float._OneTenth = new Float(
  568.     new UnsignedInt([1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1].reverse()),
  569.     new UnsignedInt([0, 1, 1, 1, 1, 0, 1, 1].reverse()),
  570.     0
  571. );*/
  572. Float._OneTenth = Float.div(Float.One, Float._Ten);
  573.  
  574. Float.fromDecimal = function (str) {
  575.     if (str.length > 2 && str.charAt(0) == '[' && str.charAt(str.length - 1) == ']')
  576.         return Float.fromBinary(str.substr(1, str.length - 2));
  577.        
  578.     if (str.charAt(0) == '-')
  579.         return Float.fromDecimal(str.substr(1)).negate();
  580.        
  581.     str = str.toLowerCase();
  582.     if (str == 'nan')
  583.         return Float.NaN;
  584.     if (str == 'inf')
  585.         return Float.PositiveInfinity;
  586.        
  587.     var match = str.match(/^(\d+)[,.]?(\d*)?$/);
  588.     if (match === null)
  589.         throw new Error('Incorrect decimal format');
  590.     var res = Float.PositiveZero;
  591.     for (var i = 0; i < str.length; i++) {
  592.         if (str.charAt(i) == ',' || str.charAt(i) == '.')
  593.             continue;
  594.         res = Float.mul(res, Float._Ten);
  595.         res = Float.add(res, Float._Digits[str.charCodeAt(i) - '0'.charCodeAt(0)]);
  596.     }
  597.     if (match[2] !== undefined) {
  598.         var digitsAfterDecimalPoint = match[2].length;
  599.         for (var i = 0; i < digitsAfterDecimalPoint; i++)
  600.             res = Float.mul(res, Float._OneTenth);
  601.     }
  602.     return res;
  603. }
  604.  
  605.  
  606. function print_bits(comment, number) {
  607.     WSH.echo(comment + ' = ' + number.toBinary());
  608. }
  609.  
  610. var fso = new ActiveXObject("Scripting.FileSystemObject");
  611. var ts = fso.OpenTextFile("input.txt", 1, true);
  612. var a = Float.fromDecimal(ts.ReadLine());
  613. var b = Float.fromDecimal(ts.ReadLine());
  614. ts.Close();
  615.  
  616. WSH.echo('FLOAT');
  617. WSH.echo('Using ' + Float._ExponentBits + ' bits for exponent, ' + Float._FractionBits + ' bits for fraction\n');
  618.  
  619. print_bits("A      ", a);
  620. print_bits("B      ", b);
  621. WSH.echo();
  622.  
  623. var compared = Float.compare(a, b);
  624. if (compared < 0)
  625.     WSH.echo('A < B');
  626. else
  627. if (compared > 0)
  628.     WSH.echo('A > B');
  629. else
  630.     WSH.echo('A = B');
  631. WSH.echo();
  632.  
  633. print_bits("A + B  ", Float.add(a, b));
  634. print_bits("A - B  ", Float.sub(a, b));
  635. print_bits("A * B  ", Float.mul(a, b));
  636. print_bits("A / B  ", Float.div(a, b));
  637. print_bits("sqrt(A)", a.sqrt());
  638. print_bits("sin(A) ", a.sin());
  639. print_bits("cos(A) ", a.cos());
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement