1

Trying to do some calculations using jquery:

Run the below snippet: put values

Quantity as 1

Buy as 111

Sell as 111.22

The result will be NaN.

Why this is happening? How to resolve this issue?

function roundToTwo(num) {
  return +(Math.round(num + "e+2") + "e-2");
}


$("#quantity, #buy, #sell").on("change keyup paste", function() {
  var quantity = Number($('#quantity').val());
  var buy = Number($("#buy").val());
  var sell = Number($("#sell").val());


  var total_amnt_trade = roundToTwo((quantity * buy) + (quantity * sell));
  var brokerage_amnt_buy = ((buy * quantity) * 0.08) / 100;
  if (brokerage_amnt_buy >= 25) {
    var brokerage_buy = 25;
  } else {
    var brokerage_buy = brokerage_amnt_buy;
  }
  var brokerage_amnt_sell = ((sell * quantity) * 0.08) / 100;
  if (brokerage_amnt_sell >= 25) {
    var brokerage_sell = 25;
  } else {
    var brokerage_sell = brokerage_amnt_sell;
  }
  var brokerage = roundToTwo(brokerage_buy + brokerage_sell); //brokerage
  var transaction_charges = roundToTwo((((buy * quantity) + (sell * quantity)) * 0.00325) / 100); //Transaction Charges
  var gst = roundToTwo((((transaction_charges * 18) / 100) + (brokerage * 18) / 100)); //GST

  var total_charges = roundToTwo(brokerage + transaction_charges + gst);
  var pnl = roundToTwo(((sell - buy) * quantity) - total_charges);

  $('#pnl_display').text(pnl);


})
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>


<table class="table table-borderless">
  <tbody>
    <tr style="text-align: center;">
      <td><b>Quantity</b></td>
      <td><b>Buy</b></td>
      <td><b>Sell</b></td>
    </tr>
    <tr>
      <td><input type="number" class="form-control" id="quantity" placeholder="Quantity" name="quantity"></td>
      <td><input type="number" class="form-control" id="buy" placeholder="Buy Amount" name="buy"></td>
      <td><input type="number" class="form-control" id="sell" placeholder="Sell Amount" name="sell"></td>
    </tr>

    <tr id="pnl_color">
      <td><span id="pnl_text_display">Profit / Loss</span></td>
      <td><span id="pnl_display"></span></td>
    </tr>

  </tbody>
</table>

Run the above snippet: put values

Quantity as 1

Buy as 111

Sell as 111.22

The result will be NaN.

Why this is happening? How to resolve this issue?

orever
  • 69
  • 1
  • 7
  • Profit/Loss is showing 100.1 for me not NaN – RK_15 Apr 11 '19 at 05:36
  • If I enter 111.22 the input will show with a red border as soon as I blur it. – connexo Apr 11 '19 at 05:38
  • It can't, by manual calculation also it will not be that much... @RK_15 – orever Apr 11 '19 at 05:38
  • @RK_15 If you input the OPs values, you will get NaN – Krishna Prashatt Apr 11 '19 at 05:38
  • @orever, there are quite a few calculations happening, did you try debugging your code? – Krishna Prashatt Apr 11 '19 at 05:40
  • seems problem in roundToTwo, if you pass something already turn into science notation, + make two "e" in string and cant be transfer back to number – waynelpu Apr 11 '19 at 05:42
  • Just update your one line as `var pnl = roundToTwo((roundToTwo(sell - buy) * quantity) - total_charges);` then it will work. – Karan Apr 11 '19 at 06:01
  • @waynelpu so what's the best option for it? – orever Apr 11 '19 at 09:48
  • @orever how many precision you need? how about round twice `Math.round(Math.round(1.005 * 1000)/10)/100` – waynelpu Apr 11 '19 at 10:13
  • @waynelpu Run this [fiddle](https://jsfiddle.net/jnpeyd61/3/) – orever Apr 11 '19 at 10:23
  • @orever as i ask you, how many precision you need?, in computer science especially js, float number has it's precision limitation, you need to know what the precision you need in your real application – waynelpu Apr 11 '19 at 10:39
  • Till the last precision (as there is a limitation else I'll go for unlimited0, as even I also don't know how many I need as I will be added by calculating 4-5 different types of percentage...(in the question I have mentioned only 2-3). – orever Apr 11 '19 at 10:43
  • @orever try this [link](https://stackoverflow.com/questions/11695618/dealing-with-float-precision-in-javascript) – waynelpu Apr 11 '19 at 10:53
  • I'll be thankful if you clear my doubts at https://stackoverflow.com/questions/55631605/calculation-of-jquery-in-while-loop – orever Apr 11 '19 at 11:43

3 Answers3

0

instead of roundToTwo you can use .tofixed(2) then problem resolves. Because your answer return with e (-1.1379786002407855e-15) so it shows NaN.

 var pnl = parseFloat(((sell - buy) * quantity) - total_charges).toFixed(2);

function roundToTwo(num) {
  return +(Math.round(num + "e+2") + "e-2");
}


$("#quantity, #buy, #sell").on("change keyup paste", function() {
  var quantity = Number($('#quantity').val());
  var buy = Number($("#buy").val());
  var sell = Number($("#sell").val());


  var total_amnt_trade = roundToTwo((quantity * buy) + (quantity * sell));
  var brokerage_amnt_buy = ((buy * quantity) * 0.08) / 100;
  if (brokerage_amnt_buy >= 25) {
    var brokerage_buy = 25;
  } else {
    var brokerage_buy = brokerage_amnt_buy;
  }
  var brokerage_amnt_sell = ((sell * quantity) * 0.08) / 100;
  if (brokerage_amnt_sell >= 25) {
    var brokerage_sell = 25;
  } else {
    var brokerage_sell = brokerage_amnt_sell;
  }
  var brokerage = roundToTwo(brokerage_buy + brokerage_sell); //brokerage
  var transaction_charges = roundToTwo((((buy * quantity) + (sell * quantity)) * 0.00325) / 100); //Transaction Charges
  var gst = roundToTwo((((transaction_charges * 18) / 100) + (brokerage * 18) / 100)); //GST

  var total_charges = roundToTwo(brokerage + transaction_charges + gst);
  var pnl = parseFloat(((sell - buy) * quantity) - total_charges).toFixed(5);
 pnl = roundToTwo(pnl);
  $('#pnl_display').text(pnl);


})
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>


<table class="table table-borderless">
  <tbody>
    <tr style="text-align: center;">
      <td><b>Quantity</b></td>
      <td><b>Buy</b></td>
      <td><b>Sell</b></td>
    </tr>
    <tr>
      <td><input type="number" class="form-control" id="quantity" placeholder="Quantity" name="quantity"></td>
      <td><input type="number" class="form-control" id="buy" placeholder="Buy Amount" name="buy"></td>
      <td><input type="number" class="form-control" id="sell" placeholder="Sell Amount" name="sell"></td>
    </tr>

    <tr id="pnl_color">
      <td><span id="pnl_text_display">Profit / Loss</span></td>
      <td><span id="pnl_display"></span></td>
    </tr>

  </tbody>
</table>
Udhay Titus
  • 5,761
  • 4
  • 23
  • 41
  • see this [comment](https://stackoverflow.com/questions/11832914/round-to-at-most-2-decimal-places-only-if-necessary#comment34941440_12830454) and the comment just below it. – orever Apr 11 '19 at 09:45
  • do you need round value if third digit of after dot is less than 5? – Udhay Titus Apr 11 '19 at 09:49
  • @orever after converting float you can round it right for eg:`.toFixed(5)` then `Math.round` you can use or Check the updated answer. – Udhay Titus Apr 11 '19 at 09:55
  • So, what will be your updated code? (Better if the codes are edited in the function **roundToTwo** it self). – orever Apr 11 '19 at 09:59
  • just I added `roundToTwo(pnl)` after converting to float. or if you use `(Math.round(num + "e+3") + "e-3")` it will works perfectly nothing issue – Udhay Titus Apr 11 '19 at 10:26
  • I'll be thankful if you clear my doubts at https://stackoverflow.com/questions/55631605/calculation-of-jquery-in-while-loop – orever Apr 11 '19 at 11:39
0

I modified yout roundToTwo() function to handle precision errors:

function roundToTwo(num) {
  return parseFloat(num.toFixed(2));
}


$("#quantity, #buy, #sell").on("change keyup paste", function() {
  var quantity = Number($('#quantity').val());
  var buy = Number($("#buy").val());
  var sell = Number($("#sell").val());


  var total_amnt_trade = roundToTwo((quantity * buy) + (quantity * sell));
  var brokerage_amnt_buy = ((buy * quantity) * 0.08) / 100;
  if (brokerage_amnt_buy >= 25) {
    var brokerage_buy = 25;
  } else {
    var brokerage_buy = brokerage_amnt_buy;
  }
  var brokerage_amnt_sell = ((sell * quantity) * 0.08) / 100;
  if (brokerage_amnt_sell >= 25) {
    var brokerage_sell = 25;
  } else {
    var brokerage_sell = brokerage_amnt_sell;
  }
  var brokerage = roundToTwo(brokerage_buy + brokerage_sell); //brokerage
  var transaction_charges = roundToTwo((((buy * quantity) + (sell * quantity)) * 0.00325) / 100); //Transaction Charges
  var gst = roundToTwo((((transaction_charges * 18) / 100) + (brokerage * 18) / 100)); //GST

  var total_charges = roundToTwo(brokerage + transaction_charges + gst);
  var pnl = roundToTwo(((sell - buy) * quantity) - total_charges);

  $('#pnl_display').text(pnl);


})
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>


<table class="table table-borderless">
  <tbody>
    <tr style="text-align: center;">
      <td><b>Quantity</b></td>
      <td><b>Buy</b></td>
      <td><b>Sell</b></td>
    </tr>
    <tr>
      <td><input type="number" class="form-control" id="quantity" placeholder="Quantity" name="quantity"></td>
      <td><input type="number" class="form-control" id="buy" placeholder="Buy Amount" name="buy"></td>
      <td><input type="number" class="form-control" id="sell" placeholder="Sell Amount" name="sell"></td>
    </tr>

    <tr id="pnl_color">
      <td><span id="pnl_text_display">Profit / Loss</span></td>
      <td><span id="pnl_display"></span></td>
    </tr>

  </tbody>
</table>
Faisal Rahman Avash
  • 1,268
  • 9
  • 13
  • See [fiddle](https://jsfiddle.net/jnpeyd61/1/) and this [comment](https://stackoverflow.com/questions/55625345/calculation-in-jquery-gives-result-nan#comment97950358_55625525) – orever Apr 11 '19 at 09:47
  • Please see if this [implementation](https://jsfiddle.net/cqb6dLze/) solves your issue – Faisal Rahman Avash Apr 11 '19 at 17:44
0

@Orever can you try again after replacing the line ( return +(Math.round(num + "e+2") + "e-2"); ) with ( return +(Math.round(num * 100) / 100); ) in the function roundToTwo(num). So your code will be

function roundToTwo(num) {
   return +(Math.round(num * 100) / 100);
}
Alok Mali
  • 2,821
  • 2
  • 16
  • 32
  • 1
    See this [fiddle](https://jsfiddle.net/jnpeyd61/) and this [comment](https://stackoverflow.com/questions/11832914/round-to-at-most-2-decimal-places-only-if-necessary#comment24719818_11832950) – orever Apr 11 '19 at 09:37