用于数据对齐的二的幂倍数
TinyPE 的汇编源代码中包含一个用于数据对齐的“简单”普通数学公式,来自以下地址:
http://www.phreedom.org/solar/code/tinype/
这是公式:
%define round(n, r) (((n+(r-1))/r)*r)
我知道它的主要目的是让像 n=31 这样的数字与 round(n, r)==32 当r=8。
我知道 n 代表预期的数字,r 是四舍五入的“基数”倍数。我还知道,鉴于它是简单的汇编源代码,所有操作仅返回整数,因此任何小数都很容易丢失,因此不会导致任何计算“错误”。
问题是下面的解释是否准确,或者是否有更好、更正确的解释。我不想盲目地使用我可能会以某种方式误解的片段。
另外,我想使用 number+(round%(number%round)),但当“number”是“round”的精确倍数时,它会导致除以零。
此公式获取最接近的数字的倍数,即 2 的幂:
在本例中,我们的数字是 31,我们想要作为“基”倍数的数字是 8。它返回 32:
(((31+(8-1))/8)*8)
首先我们得到 8-1,它给出7. 将其与 31 相加,得到 38。
然后除以 38/8,得到 4.75。由此,整数值为 4。
这个 4 乘以 8,得到 32。
每个公式部分的逻辑/数学意图如下:
-- 8-1 部分使得存在过量,无论是否原始数字(在本例中为 31)是否是基本舍入数(在本例中为 8)的倍数,并且给出了包含 7 个非倍数和可能的倍数的范围。 -1 导致我们不会通过直接转到下一个非最近的倍数来得到错误的计算,但它只是给出了一个不精确的余量来检测其余的先前“因子”。
-- 通过将这个超出的数字除以基本倍数(在本例中为 8),在其整数部分中,我们仅得到之前的因子。我们添加到它的多余部分使得该数字与最接近的倍数对齐,如果它在直接范围内而不向前最多两个倍数(因此为-1)。
-- 通过将该因子的纯整数部分(在本例中为 4)乘以基本倍数 r(在本例中为 8),我们可以得到最接近的倍数,而无需进行下一个倍数。例如,从 31 开始,最接近的 8 倍数是 32,而不是 40。
There is a "simple" plain math formula for data alignment contained in the assembly source code of TinyPE, from this address:
http://www.phreedom.org/solar/code/tinype/
This is the formula:
%define round(n, r) (((n+(r-1))/r)*r)
I know that its main intention is to get numbers like n=31 aligned to something like round(n,r)==32 when r=8.
I know that n represents the intended number and r is the rounding "base" multiple. I also know that, given it is simple assembly source code, all operations return integer numbers only, so any decimals are conveniently lost and thus don't cause any calculation "errors".
The question is whether the following explanation is accurate, or if there is a better, more correct one. I don't want to blindly use a snippet I could be misunderstanding somehow.
Also, I would have liked to use number+(round%(number%round)), but it causes division by zero when "number" is an exact multiple of "round".
This formula gets the nearest multiple of a number which is power of two:
In this example our number is 31 and the number we want to have as "base" multiple is 8. It returns 32:
(((31+(8-1))/8)*8)
First we get 8-1, which gives 7. We add it to 31, which gives 38.
Then we divide 38/8, which gives 4.75. From this, the integer value is 4.
This 4 is multiplied by 8, which gives 32.
The logical/mathematical intention of each of these formula parts is as follows:
-- The 8-1 parts makes that an excess be present, whether the original number (in this case 31) is a multiple or not of the base rounding number (in this case 8), and that gives a range that goes through 7 non-multiple numbers and a possible multiple. The -1 causes that we don't get the wrong calculation by going right to the next non-nearest multiple but it just gives an inexact margin to detect the rest of previous "factors".
-- By dividing this exceeded number by the base multiple (8 in this case), in its integer part, we get only the previous factors. The excess that we add to it makes that the number gets aligned to the nearest multiple, if it's within the immediate range without going up to two multiples ahead (hence the -1).
-- By multiplying the purely integer part of this factor (4 in this case) by the base multiple r (8 in this case), we get the exact nearest multiple, without going to the next one. For instance the nearest multiple of 8, starting from 31, is 32, not 40.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不太确定我理解你的问题,但如果你想找到最接近给定数字 x 的 n 的幂,你可以尝试
n^(round(ln(x)/ln(n))
I am not quite sure I understand your question, but if you wish to find the power of n closest to a given number x you could try
n^(round(ln(x)/ln(n))