向下舍入浮点数的最近整数幂

时间:2013-06-18 15:46:59

标签: c++ qt zooming

给定两个浮点值zoomAmountzoomFactor,我需要计算一个newZoomAmount,以便:{/ p>

(newZoomAmount <= zoomAmount) && (newZoomAmount == pow( zoomFactor, i ))

表示任何整数i。我可以轻松地遍历值或通过表格进行二进制搜索来找到答案。但是:有没有一个封闭的形式来实现这个目标?


动机zoomFactor是2 1.148698354997035,因此每次5次“放大”事件会产生〜精确的力量两个增加。当缩放图表以适应屏幕时,我希望缩放级别是这些凹槽中的一个,因此缩小最终会准确地落在“基本”1.0缩放级别上。

4 个答案:

答案 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 == 2zoomFactor6 == 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

我们使用减量的上限而不仅仅是最低限度的原因是为了处理zoomAmountzoomFactor的完美力量的特殊情况,在这种情况下

⌊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 */