JavaScript Snippet – A Human-Readable Memory-Formatter, Add Commas To A Number By Regular-Expression

function human_readable_bytes_size(bytes, decimals, sap) {
  decimals = "number" === typeof decimals ? decimals : 2;
  sap = "string" === typeof sap ? sap : "";

  var 
    size = ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
  , factor = Math.floor(  (String(bytes).length - 1) / 3  )
  ;
  
  bytes = bytes / Math.pow(1024, factor);  //calc
  bytes = Math.floor(bytes * Math.pow(10, decimals)) / Math.pow(10, decimals);  //round digits
  
   
  return String(bytes) + sap + size[factor];
}



human_readable_bytes_size(29)
//"29B"
human_readable_bytes_size(29000000000000000)
//"25.75PB"
human_readable_bytes_size(2900000000000)
//"2.63TB"
human_readable_bytes_size(290000000000)
//"270.08GB"
human_readable_bytes_size(290000000000,5)
//"270.08354GB"
human_readable_bytes_size(290000000000,5,"---")
//"270.08354---GB"

also available on GitHub: https://github.com/eladkarako/javascript_human_readable_bytes_size

Would you like the PHP version? – http://icompile.eladkarako.com/php-snippet-a-human-readable-memory-formatter-add-commas-to-a-number-by-regular-expression/


This is a variation with comma-separation (only for the integer part since the fraction part looks weird w/ commas..)

function human_readable_bytes_size(bytes, digits, sap, is_comma_sap) {  "use strict";
  digits       = "number"  === typeof digits        ? digits         :  2;
  sap          = "string"  === typeof sap           ? sap            : "";
  is_comma_sap = "boolean" === typeof is_comma_sap  ? is_comma_sap   : false;

  var  size = ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
     , factor = Math.floor(  (String(bytes).length - 1) / 3  )
     ;

  bytes = bytes / Math.pow(1024, factor);  //calc
  bytes = Math.floor(bytes * Math.pow(10, digits)) / Math.pow(10, digits);  //round digits
  
  if(true === is_comma_sap){
    bytes = String(bytes).split(".");
    bytes[0] = bytes[0].replace(/(\d)(?=(\d{3})+$)/g, "$1,");
    bytes = bytes.join(".");
  }

  return String(bytes) + sap + size[factor];
}

since it is very rare (actually improbable) to use the comma-feature when measuring to the largest scale available,
– In my project https://github.com/eladkarako/any2base64 I’m using a slightly different variation that actually ‘reduce a scale by one’ meaning, instead of using 1GB it will use 1024MB (or 1000-MiB..
* [1] [2])

It works nicely, and sometimes helps to comprehend byte sizes more clearly… Ahhh.. human perspective! ;] ;]


Update:

Here is another variation:
1. it breaks with an error, which is useful for simpler to use within try/catch
without need to pre-check the input is valid.
2. it allows a full/long description.

function human_readable_bytes_size(bytes, decimals, sap, is_desc_short) {
  bytes          = Number(bytes);                                              //normalize input.
  decimals       = "number"  === typeof decimals      ? decimals      : 2;     //
  sap            = "string"  === typeof sap           ? sap           : "";    //
  is_desc_short  = "boolean" === typeof is_desc_short ? is_desc_short : true;  //

  if(true === /NaN/i.test(String(bytes)))                         //handle invalid input.
    throw new Error("\"bytes\" Input-Argument Is NOT A Number.");

  var factor     = Math.floor(  (String(bytes).length - 1) / 3  )
     ,desc_short = ['B',     'kB',        'MB',        'GB',        'TB',        'PB',        'EB',       'ZB',         'YB']
     ,desc_long  = ['Bytes', 'KiloBytes', 'MegaBytes', 'GigaBytes', 'TeraBytes', 'PetaBytes', 'ExaBytes', 'ZettaBytes', 'YottaBytes']
     ;

  bytes = bytes / Math.pow(1024, factor);  //calc
  bytes = Math.floor(bytes * Math.pow(10, decimals)) / Math.pow(10, decimals);  //round digits

  return  String(bytes)
        + sap
        + (true === is_desc_short ? desc_short[factor] : desc_long[factor])
        ;
}

and using it with:

console.log(
  human_readable_bytes_size(10000000000000,3," ",false)
);

//will give you "9.095 TeraBytes"

and

human_readable_bytes_size("a10000000000000",3," ",false)

//will give you something like...
//Uncaught Error: "bytes" Input-Argument Is NOT A Number.