0

Days ago, I started a project in which i needed to do some measure calculation; specifically: statistic calculation. Well, thats not the problem, the problem came with rounding floating numbers (numbers with decimals), and the way javascript deals with it. I found some approaches in internet to rounding javascript numbers, but none of them was great alternatives to what exactly ms excel does (ROUND.MAX function). So I have to recreate that function behavior by myself. So this is the code:

MathExt = {

 init: function(options){
  this.separator = options.separator || ",";
 },

 roundMax: function(number, decimals){
  var $_indexOf = number.lastIndexOf(this.separator);
  var fp = number.substring(0, $_indexOf);
  var rp = number.substr($_indexOf + 1);
  var roundedNumber = "";
  if(decimals > 0){
   var i = 0;
   var _pq = 0;
   var _zeros = "";

   while(rp.substr(i++, 1) == "0"){ _zeros += "0"; }

   i = rp.length - 1;
   while(i >= decimals){
    var _t = rp.charAt(i);
    rp = rp.substring(0, i);
    if(_t != "0"){
     if(rp.charAt(i - 1) == "9"){ _pq  = 1; }
     else{ 
      if(_pq == 1) _pq = 0;
      rp = _zeros + (parseInt(rp, 10) + 1) + "";
      if(i == _zeros.length) _zeros = _zeros.substr(0, i - 1);
     }
    }
    i--;
   }
   if(_pq == 0)
    roundedNumber = fp + this.separator + rp;
   else
    if(i == 0){
     roundedNumber = "" + (parseInt(fp) + 1);
    }
    else{
     rp = (parseInt(rp) + 1) + "";
     i = rp.length - 1;
     while(i > 0 && rp.substr(i, 1) == "0" ) rp = rp.substr(0, i);
     roundedNumber = fp + this.separator +  rp;
    }
  }
  else{
   var _s = rp.substring(0, 1);
   if(_s != "0") fp = "" + (parseInt(fp) + 1);
   roundedNumber = fp;
  }
  return roundedNumber;
 }
};

Well, this code works as I expeted with javascript numbers. but Surpringly javascript truncate long floating numbers. And the next is to do the same but with really long numbers. Yesterday someone gave me a link which I found really useful, but. I wanna know if this function (ROUND.MAX from EXCEL) is already implemented for this kind of big floating numbers.

This is an example:

piii = 3.14159141597; for(var i = 0; i <= 11; i++){ console.log((Math.round((piii*Math.pow(10, i)))/Math.pow(10,i))); } extracted this from internet.
3
3.1
3.14
3.142
3.1416
3.14159
3.141591
3.1415914
3.14159142
3.141591416
3.141591416
3.14159141597

MS Excel ROUND.MAX FUNCTION
4
3,2
3,15
3,142
3,1416
3,1416
3,141592
3,1415915
3,14159142
3,141591416
3,141591416
3,14159141597

My first version of the ROUND.MAX algorithm
4
3.2
3.15
3.142
3.1416
3.1416
3.141592
3.1415915
3.14159142
3.141591416
3.141591416
3.14159141597
Jota
  • 17,281
  • 7
  • 63
  • 93
crsuarezf
  • 1,201
  • 3
  • 18
  • 33
  • 1
    Are you representing numbers as strings? – thejh Nov 27 '10 at 16:46
  • Well, in principle, all the data is stored in SQLServer, and the fields which store the information are text. So, The input is text, right. – crsuarezf Nov 27 '10 at 17:03
  • For example: There are values like: 3.5 and 3,5 note the (dot and comma) There are also values like: 3.56246323457213471283904712839047128930423074891203748129037481290347812903471823904712839047128930471283904718 note the (big number) those value are inmediatly truncated in javascript, and I don't wanna waste server time and processor in those calculations, because I'm using the server as a simple CRUD interface, so all the calculation is being doing in the client with javascript. – crsuarezf Nov 27 '10 at 17:10

1 Answers1

2

Just replace round with ceil in your example to get the roundmax effect:

piii = 3.14159141597;
for(var i = 0; i <= 11; i++) { 
    console.log((Math.ceil((piii*Math.pow(10, i)))/Math.pow(10,i)));
}

Output:

4
3.2
3.15
3.142
3.1416
3.1416
3.141592
3.1415915
3.14159142
3.141591416
3.141591416
3.14159141597
xan
  • 7,511
  • 2
  • 32
  • 45