我有一个脚本的问题,我不明白发生了什么事情。
这里是 :
let angle = 0 let multiplier = .01 function raf() { if(angle >= 1 || angle < 0) { multiplier = - multiplier } angle = angle + multiplier if(angle < 0) console.log(angle) requestAnimationFrame(raf) } requestAnimationFrame(raf)目标是提高0.01的角度,当它达到1时,应该减少到0,然后再提高到1。
我有时会得到一个负面的角度(-8.etc),我不明白为什么(console.log应该表明这一点)。
我为此做了一个笔: https : //codepen.io/mourtazag/pen/QvjjLy
谢谢你们 !
Mourtaza。
I have a problem with a script, I don't understand what's going wrond.
Here it is :
let angle = 0 let multiplier = .01 function raf() { if(angle >= 1 || angle < 0) { multiplier = - multiplier } angle = angle + multiplier if(angle < 0) console.log(angle) requestAnimationFrame(raf) } requestAnimationFrame(raf)The purpose is the angle to raise by 0.01 and when it reaches 1, it should decrease to 0 and then raise again to 1.
I sometimes get a negative angle (-8.etc) and I don't understand why (the console.log is supposed to show that).
I made a pen for that : https://codepen.io/mourtazag/pen/QvjjLy
Thank you all !
Mourtaza.
最满意答案
您没有收到-8 ,您会收到-8.XXXXXXe-17 。 注意最后的e-17 。 这是科学记数法,所以你的数字实际上是-0.00000000000000008XXXXX 。 您可以使用angle.toFixed(20)在没有科学记数法的情况下查看浮点数。 数字是您要显示的小数位数。
为什么如果你只增加和减少0.01你会得到这么小的数字? 你可以问。 发生这种情况是因为浮点数不准确,因为小数不可能被“保存到最后”,而不是整数。 例如,可以考虑具有无限小数的1/3 。 在这里,您可以阅读更多关于JavaScript和浮点精度的信息: 在Javascript中处理float精度
另一个问题是有一个消极的角度(这么小,但仍然是负面的,虽然你实际检查负角度)。 发生这种情况是因为你在增加/减少它之前检查负角度,所以如果你的乘数为负数,并且你的角度为0.0001whatever (因为浮点精度问题),它仍然高于零,所以你乘数仍然是负值,但实际上大于你的角度,所以当乘数应用时,角度将是负值。
我可以想办法解决这个问题:
let angle = 0 let multiplier = .01 function raf() { angle = angle+multiplier; if(angle > 1 || angle < 0) { multiplier = -multiplier angle = angle<0?0:1; } console.log(angle.toFixed(20)) requestAnimationFrame(raf) } requestAnimationFrame(raf)有了这个,你可以检查你的角度是否在工作之后的极限内,所以你会克服精度问题: https : //codepen.io/anon/pen/eWppGy
另一种方法可以是使用整数(因为它们没有精度问题,正如我上面所述),并且在使用整数时将角度除以100,如下所示:
let angle = 0 let multiplier = 1 function raf() { angle = angle+multiplier; if(angle >= 100 || angle <= 0) { multiplier = -multiplier; angle = angle<=0?0:100; } console.log(angle/100) requestAnimationFrame(raf) } requestAnimationFrame(raf)笔: https : //codepen.io/anon/pen/XRmmVq
You don't receive -8, you receive -8.XXXXXXe-17. Note the e-17 at the end. That's scientific notation, so your number is actually -0.00000000000000008XXXXX. You can see the float number without scientific notation using angle.toFixed(20). The number is the amount of decimals that you want to show.
Why you get such small numbers if you are only increasing and decreasing by 0.01? may you ask. This happens because floating points are not exact as decimals are impossible to be "saved to the end", not like integers. Think of 1/3 having an infinite numbers of decimals, for example. Here you can read more about JavaScript and float precision: Dealing with float precision in Javascript
The other problem is having a negative angle (such small, but still negative although you actually check for negative angles). This happens because you check for negative angles BEFORE increasing/decreasing it, so if you have your multiplier as negative and your angle as, let's say, 0.0001whatever (because of the float precision problem), it is still above zero, so you multiplier is still going to be negative, but is actually bigger than your angle, so when the multiplier is applied, the angle will be negative.
I can think of this way to solve this problem:
let angle = 0 let multiplier = .01 function raf() { angle = angle+multiplier; if(angle > 1 || angle < 0) { multiplier = -multiplier angle = angle<0?0:1; } console.log(angle.toFixed(20)) requestAnimationFrame(raf) } requestAnimationFrame(raf)With this, you check if your angle is inside the limits AFTER working on it, so you will overcome the precision problem: https://codepen.io/anon/pen/eWppGy
Another way can be to use integers (because they don't have the precision problem, as I stated above) and divide the angle by 100 when going to work with it, like this:
let angle = 0 let multiplier = 1 function raf() { angle = angle+multiplier; if(angle >= 100 || angle <= 0) { multiplier = -multiplier; angle = angle<=0?0:100; } console.log(angle/100) requestAnimationFrame(raf) } requestAnimationFrame(raf)Pen: https://codepen.io/anon/pen/XRmmVq
更多推荐
发布评论