提问人:hippietrail 提问时间:9/10/2017 更新时间:9/10/2017 访问量:1824
确定浮点数中的前导零数
Determine number of leading zeros in a floating point number
问:
如何计算浮点数中小数点后、第一个非零点之前有多少个零。例子:
0 -> 0
1 -> 0
1.0 -> 0
1.1 -> 0
1.01 -> 1
1.00003456 ->4
凭直觉,我假设有一个数学函数可以提供这一点,或者至少可以完成主要部分。但我既不记得也不知道是哪一个。
我知道这可以通过首先将数字转换为字符串来完成,只要数字不是科学记数法,但我想要一个纯粹的数学解决方案。
就我而言,如果这是一个复杂的问题,我不需要适用于负数的东西。
我想知道一般的方法是什么,不管语言如何。
但是,如果有一个非常标准的数学函数,我也想知道 JavaScript 是否有这个函数。
顺便说一句,我想知道这种计算是否与确定整数的十进制表示需要多少位数的方法有关。
答:
你可以用方法来做,但我的代码中只有一个缺陷,你需要指定点后面的数字的长度,这是因为方法的使用方式。toFixed()
.
注意:
方法的最大长度为 20,因此不要按照文档中所述输入超过 20 个数字toFixed()
.
var num = 12.0003400;
var lengthAfterThePoint = 7;
var l = num.toFixed(lengthAfterThePoint);
var pointFound = false;
var totalZeros = 0;
for(var i = 0; i < l.length; i++){
if(pointFound == false){
if(l[i] == '.'){
pointFound = true;
}
}else{
if(l[i] != 0){
break;
}else{
totalZeros++;
}
}
}
console.log(totalZeros);
额外答案
这是我的额外答案,在这个函数中,程序计算所有零,直到最后一个非零。因此,它忽略了末尾的所有零。
var num = 12.034000005608000;
var lengthAfterThePoint = 15;
var l = num.toFixed(lengthAfterThePoint);
var pointFound = false;
var theArr = [];
for(var i = 0; i < l.length; i++){
if(pointFound == false){
if(l[i] == '.'){
pointFound = true;
}
}else{
theArr.push(l[i]);
}
}
var firstNumFound = false;
var totalZeros = 0;
for(var j = 0; j < theArr.length; j++){
if(firstNumFound == false){
if(theArr[j] != 0){
firstNumFound = true;
totalZeros = totalZeros + j;
}
}else{
if(theArr[j] == 0){
totalZeros++;
}
}
}
var totalZerosLeft = 0;
for (var k = theArr.length; k > 0; k--) {
if(theArr[k -1] == 0){
totalZerosLeft++;
}else{
break;
}
}
console.log(totalZeros - totalZerosLeft);
你可以通过一个简单的循环来做到这一点:while
function CountZeros(Num) {
var Dec = Num % 1;
var Counter = -1;
while ((Dec < 1) && (Dec > 0)) {
Dec = Dec * 10;
Counter++;
}
Counter = Math.max(0, Counter); // In case there were no numbers at all after the decimal point.
console.log("There is: " + Counter + " zeros");
}
然后只需将要检查的数字传递到函数中:
CountZeros(1.0034);
评论
1.0000340001120
假设是一个非整数,可以写成整个部分的数字,然后是小数点,然后是零,然后是小数部分的其余部分。x
n
m
x = [一个1一个2...一个n] . [0102...0米][b1b2...B米]
这意味着 的小数部分大于或等于 10–m,小于 10–m+1。x
换言之,小数部分的十进制对数大于或等于 ,小于 。x
–m
–m+1
反过来,这意味着 的小数部分的十进制对数的整个部分等于 .x
–m
function numZeroesAfterPoint(x) {
if (x % 1 == 0) {
return 0;
} else {
return -1 - Math.floor(Math.log10(x % 1));
}
}
console.log(numZeroesAfterPoint(0));
console.log(numZeroesAfterPoint(1));
console.log(numZeroesAfterPoint(1.0));
console.log(numZeroesAfterPoint(1.1));
console.log(numZeroesAfterPoint(1.01));
console.log(numZeroesAfterPoint(1.00003456));
顺便说一句,我想知道这种计算是否与确定整数的十进制表示需要多少位数的方法有关。
以同样的方式,正整数采用十进制数字来表示它,当且仅当 .x
n
n - 1 <= log10(x) < n
所以十进制表示中的位数是 。x
floor(log10(x)) + 1
也就是说,我不建议在实践中使用这种确定位数的方法。 不能保证给出对数的精确值(甚至不如 IEEE 754 允许的精确),这可能会导致在某些边缘情况下出现错误的结果。log10
评论
1.001
我的方法是使用一个循环,将值与它的值进行比较,同时递增直到两者不相等:while()
.floor(n)
n.toFixed(x)
x
console.log(getZeros(0)); //0
console.log(getZeros(1)); //0
console.log(getZeros(1.0)); //0
console.log(getZeros(1.1)); //0
console.log(getZeros(1.01)); //1
console.log(getZeros(1.00003456)); //4
function getZeros(num) {
var x = 0;
if(num % 1 === 0) return x;
while(Math.floor(num)==num.toFixed(x)) {x++;}
return(x-1);
}
评论
1.001
1.001
上一个:如何为所有对象设置类别
评论