给定两个浮点值zoomAmount
和zoomFactor
,我需要计算一个newZoomAmount
,以便:{/ p>
(newZoomAmount <= zoomAmount) && (newZoomAmount == pow( zoomFactor, i ))
表示任何整数i
。我可以轻松地遍历值或通过表格进行二进制搜索来找到答案。但是:有没有一个封闭的形式来实现这个目标?
动机:zoomFactor
是2 ⅕≅1.148698354997035
,因此每次5次“放大”事件会产生〜精确的力量两个增加。当缩放图表以适应屏幕时,我希望缩放级别是这些凹槽中的一个,因此缩小最终会准确地落在“基本”1.0缩放级别上。
答案 0 :(得分:4)
表示:
A = zoomAmount
F = zoomFactor
newA = newZoomAmount
我们有:
newA = pow(F, i)
=> log(newA) = i*log(F)
=> i = log(newA)/log(F)
和newA&lt; = A,并且log不减少,
i = floor(log(A)/log(F))
newZoomAmount = pow( zoomFactor, floor( log(zoomAmount)/log(zoomFactor) ) );
答案 1 :(得分:2)
基本上,对数。我会忽略log
的底层实现可能会迭代的事实,因为你可能不介意。
使用以下内容:
zoomFactor = 21/5 = 1.148698354997035 zoomAmount = 2.25
您需要找到以下内容(请注意,我使用的内容少于或小于等于,请参阅结尾以了解原因):
(newZoomAmount < 2.25) && (newZoomAmount == 2i/5)
通过检查,我们知道(自zoomFactor5 == 2
和zoomFactor6 == 2.297... > 2.25
)
newZoomAmount == 2 i == 5
因此,要获得指数的当前zoomAmount
,我们采取:
zoomExponent = log(zoomAmount) / log(zoomFactor) = 0.81093... / 0.13862... = 5.84962...
要获得下一个最低整数,您应该减去1,然后取上限。
newZoomExponent = ⌈zoomExponent - 1⌉ = ⌈4.84962...⌉ = 5
最后:
newZoomAmount = zoomFactornewZoomExponent
我们使用减量的上限而不仅仅是最低限度的原因是为了处理zoomAmount
是zoomFactor
的完美力量的特殊情况,在这种情况下
⌊zoomExponent⌋ == zoomExponent
newZoomAmount == zoomAmount
我们显然不想要。
答案 2 :(得分:1)
只需替换并重新评估:
(newZoomAmount <= zoomAmount) && (newZoomAmount == pow( zoomFactor, i ))
=&gt; pow( zoomFactor, i ) <= zoomAmount
=&gt; i * ln(zoomFactor) <= ln(zoomAmount)
=&gt; i <= ln(zoomAmount) / ln(zoomFactor)
可能会或可能不会比迭代更快。
然后只需指定newZoomAmount = pow( zoomFactor, i );
答案 3 :(得分:1)
exponent=log(zoomAmount)/log(zoomFactor); /* zoomFactor^exponent == zoomAmount */
newZoomAmount=pow(zoomFactor,floor(exponent)); /* round down exponent */