把数字转换成每隔几位加分隔符分隔算法实现。

181 阅读1分钟

1、先看一个简单的实现num.toLocalString()效果

实现1123145100-->1,123,145,100的效果。算法代码如下:主要是采用数值除1000的余数拼接操作。 本文主要思路是:先做正整数处理的算法,然后再做边界问题、负数和浮点数的处理算法。

function numToStr(num: number): string {
  let res = "";  //存储结果
  while (true) {
    let t = num % 1000;   //获取后‘三位数’,即余数
    num = (num - t) / 1000;  //num去掉后三位数
    // 后三位数进入拼接程序
    res = t < 10 ? `,00${t}` + res : t < 100 ? `,0${t}` + res : `,${t}` + res;  
    if (num < 1000) {  //结束while循环和函数体条件,最后的num小于1000不需要再进入循环
      //边界情况,最后的数没有三位,直接进行拼接,并返回结果
      res = num + res;
      return res;
    }
  }
}

//结果测试和性能比较
console.time("b");
let b =
  (1241500001241247184371837481294712492421500001241247184371837481294712492415000012412471843718374812947124924304032000000000000000000000003100).toLocaleString();
console.log("🚀 ~ file: test.ts ~ line 17 ~ b", b);
console.timeEnd("b");

console.time("a");
let a =
  numToStr(
    1241500001241247184371837481294712492421500001241247184371837481294712492415000012412471843718374812947124924304032000000000000000000000003100
  );
console.log("🚀 ~ file: test.ts ~ line 17 ~ a", a);
console.timeEnd("a");

结果如下:

image.png

核心步骤解释: res = t < 10 ? `,00${t}` + res : t < 100 ? `,0${t}` + res : `,${t}` + res; 其中t为模(除)1000的余数,如果为一位数,则拼接‘,00’+t;如果为两位数。则拼接‘,0’+t;否则,为三位数,直接拼接。

其中:字符串加数字的结果为字符串。

2、升级优化,支持定义分隔几位数和分隔符

核心代码:

function numToStr(num: number, n: number, g: string = ","): string {
  let res = "", ls = "",i = 1;
  const divisor = Math.pow(10, n);
  while (i < n) {
    i++;
    ls += 0;
  }
  while (true) {
    let t = num % divisor;
    num = (num - t) / divisor;
    res = g + `${ls}${t}`.slice(-n) + res;
    if (num < divisor) {
      res = num + res;
      return res;
    }
  }
}

console.time("b");
let b =
  (1241500001241247184371837481294712492421500001241247184371837481294712492415000012412471843718374812947124924304032000000000000000000000003100).toLocaleString();
console.log("🚀 ~ file: test.ts ~ line 17 ~ b", b);
console.timeEnd("b");

console.time("a");
let a = numToStr(
  1241500001241247184371837481294712492421500001241247184371837481294712492415000012412471843718374812947124924304032000000000000000000000003100,
  3,
  "-"
);
console.log("🚀 ~ file: test.ts ~ line 17 ~ a", a);
console.timeEnd("a");

image.png

3、边界问题处理,数字的最大表示2^53 -1 ,超过max_safe_number或min_safe_number

仔细观察前面两个算法和结果,是有问题的!没做输入边界问题处理超出,输入超过安全数会出现错误结果,有可能会出现bug。更新输入边界问题处理如下:

function better(num: number, n: number, g: string = ","): string {
  //边界问题处理,边界问题,负数问题,小数点问题
  if (num > Number.MAX_SAFE_INTEGER) return "超过最大安全数啦";
  if (num < Number.MIN_SAFE_INTEGER) return "超过最小安全数啦";
  let b = "";
  if (num < 0) {
    b = "-";
    num = -num;
  }
  return (
    b +
    numToStr(Math.floor(num), n, g) +
    (`${num}`.split(".")[1] ? "." + `${num}`.split(".")[1] : "")
  );
}

console.time("b");
let b = (1241500001.1212).toLocaleString();
console.log("🚀 ~ file: test.ts ~ line 17 ~ b", b);
console.timeEnd("b");

console.time("a");
let a = better(-1241232500001.122, 3, "-");
console.log("🚀 ~ file: test.ts ~ line 17 ~ a", a);
console.timeEnd("a");

结果如下:

image.png