在平常得开发里,有时候会遇到让保留有效数字,比方说
-
若数值 >=10,则去尾保留 3 位小数,结果去掉小数末尾的 0。
- 10.12345去尾保留3位小数,结果为10.123。
- 10.00000去尾保留3位小数,并去掉小数末尾的0,结果为10。
-
若数值 <10 ,则去尾保留 5 位有效数字,结果去掉小数末尾的 0。
- 0.0000012345678去尾保留5位有效数字,结果为0.0000012345。
- 0.0000012去尾保留5位有效数字,并去掉小数末尾的0,结果为0.0000012。
- 0.100===>0.1
- 0.00100===>0.001
- 9.0001234===>9.0001。
- 9.0120003===>9.012。
- 9.00001==>9
话不多说,直接开干
function significantDigits(val) {
if (!val) {
return val
}
let valArr = (val + '').split('.');
console.log('valArr', valArr);
if (valArr.length === 1) {
// 整数直接返回
return val
}
let res = '';
if (val >= 10) {
// 数值>=10,去尾保留3位小数,结果去掉小数末尾的0
this.getThree(valArr[1], 3) ? res = valArr[0] + '.' + this.getThree(valArr[1], 3) : res = valArr[0];
console.log('res', res);
return res
}
console.log('valArr[0]', valArr[0]);
// 若数值<10,则去尾保留5位有效数字,结果去掉小数末尾的0。
// 注意:前面的整数也要计算位数 但如果是大于等于1的 那整数位没有0 小于1 得话 整数位就也是0
if (valArr[0] >= 1) {
// 整数位大于等于1 整数要计入位数 后面只要4位了
this.getThree(valArr[1], 4) ? res = valArr[0] + '.' + this.getThree(valArr[1], 4) : res = valArr[0];
console.log('res', res);
return res
}
if (valArr[0] < 1) {
// 整数位小于1 那就是0开头 整数不计入位数 从第一个不是0的数字开始算
res = valArr[0] + '.' + this.findNum(valArr[1], 5);
console.log('res', res);
return res
}
}
// 处理的的大于等于1的 这种是第一位已经确定了 只需要在小数点后面搞固定位数即可
function getThree(val, num) {
// 先截取num个小数,并且去掉尾巴为0的
let arr = [];
// 有没有需要的位数那么多个 有的话直接截取 没有 就直接源数据去尾返回即可
val.length <= num ? (arr = val.split('')) : (arr = val.slice(0, num).split(''));
console.log('arr', arr);
while (arr[arr.length - 1] == 0) {
arr.pop()
}
// 注意 这儿有全部为0的情况 这样arr就是空数组 所以上面的res赋值需要判断一下
return arr.join('')
}
// 处理 0.xxx这种得小数 这种是第一位从哪儿开始算都还没确定 得先确定位,然后再处理后面的数字
function findNum(val, num) {
let result = ''
if (val) {
let arr = val.split('');
let newArr = [];
let i = 0;
while (arr[i] == 0) {
// 先把0搞进去
newArr.push(arr[i])
i++
}
// 这儿已经确定了第一位了 从这儿开始再往后num个就行
let index = i + num;
while (i < index) {
// 有效数字搞进去
newArr.push(arr[i])
i++
}
// 不够位数就push空进去了 所以这儿需要处理一下
newArr = newArr.filter(i => i);
console.log('newArr', newArr);
// 去尾
while (newArr[newArr.length - 1] == 0) {
newArr.pop()
}
console.log('newArr1', newArr);
result = newArr.join('')
}
return result
}
// significantDigits(10.12345) 10.123
// significantDigits(10.00000) 10
// significantDigits(10.001) 10.001
// significantDigits(10.010) 10.01
// significantDigits(9.00001) 9.00001
// significantDigits(9.0001234 ) 9.0001
// significantDigits(9.0120003) 9.012
// significantDigits(0.0000012345678) 0.0000012345
// significantDigits(0.0000012) 0.0000012
// significantDigits(0.10001) 0.10001
// significantDigits(0.100) 0.1
// significantDigits(0.00100) 0.001
思路就是先做大的区分
- 大于等于10的这种整数位是确定的,直接保留3位小数去尾即可
- 小于10的就有两种情况
- 一种是大于等于1的,这种整数位也是确定的,直接截取4位小数,然后去尾即可
- 另外一种是小于1的,这种第一位有效数字就需要去确定,得挨个挨个去找,知道找到那个不为0得开始,再往后去截取、去尾即可
但是有时候事情往往不是这么简单,有时候拿到的数字是科学计数法。。。
// 科学计数转化为小数
function myToFixed(inputNumber) {
if (isNaN(inputNumber)) {
return inputNumber
}
inputNumber = '' + inputNumber
inputNumber = parseFloat(inputNumber)
let eformat = inputNumber.toExponential() // 转换为标准的科学计数法形式(字符串)
let tmpArray = eformat.match(/\d(?:\.(\d*))?e([+-]\d+)/) // 分离出小数值和指数值
let number = inputNumber.toFixed(Math.max(0, (tmpArray[1] || '').length - tmpArray[2]))
return number
}