有什么方法可以不用循环计算 1.01^x,仅使用整数加法、乘法、子法、div、exp?
Is there any way to compute 1.01^x without loops, using only integer add, mul, sub, div, exp?
有什么方法可以实现 Uint256 -> Uint256
函数 f(x) = floor(1.01 ^ x)
,只使用固定数量的操作 add
, mul
, sub
, [ =16=, exp
, 都是只能对整数运算吗?
使用牛顿二项式级数
(1+h)^x = 1+x*h + x*(x-1)/2*h^2 + x*(x-1)*(x-2)/6*h^3 + ...
= 1 + x*h*(1+(x-1)*h/2*(1+(x-2)*h/3*(1+...)))
要获得终止计算,首先必须减少 x
,我认为是 log(2)/log(1.01)
的倍数。
本质上,在中间结果中你必须使用某种定点算法。
我会尝试固定点。假设您的 Int256
是无符号 8 位整数,然后尝试 8.8
或 8.16
或 8.32
固定格式。取决于你需要什么精度。
让我们将数字重写为 a.b
格式并假设 8.16
(8.8
根据我的口味忽略了太多的 1.01
二进制)所以你得到:
1.01^x = (1+0.01*65536/65536)^x = (1+655/65536)^x
a=1
b=655
现在只需计算整数 pow
,例如用平方的幂,请参阅:
然后将结果转换回整数,因此
floor
(仅使用 a
)
round
(增加 a
如果 b>32767
)
为了避免循环,只需将功率平方成几行复制粘贴行(每个位一个)。
顺便说一句,如果你意识到你乘以:
,这可以用 +,<<
来完成
1.01dec = 1.0000001010001111 bin
所以你可以为每个二进制 1
而不是 mul
做 shift
和 add
以防 mul
是一个问题...
有什么方法可以实现 Uint256 -> Uint256
函数 f(x) = floor(1.01 ^ x)
,只使用固定数量的操作 add
, mul
, sub
, [ =16=, exp
, 都是只能对整数运算吗?
使用牛顿二项式级数
(1+h)^x = 1+x*h + x*(x-1)/2*h^2 + x*(x-1)*(x-2)/6*h^3 + ...
= 1 + x*h*(1+(x-1)*h/2*(1+(x-2)*h/3*(1+...)))
要获得终止计算,首先必须减少 x
,我认为是 log(2)/log(1.01)
的倍数。
本质上,在中间结果中你必须使用某种定点算法。
我会尝试固定点。假设您的 Int256
是无符号 8 位整数,然后尝试 8.8
或 8.16
或 8.32
固定格式。取决于你需要什么精度。
让我们将数字重写为 a.b
格式并假设 8.16
(8.8
根据我的口味忽略了太多的 1.01
二进制)所以你得到:
1.01^x = (1+0.01*65536/65536)^x = (1+655/65536)^x
a=1
b=655
现在只需计算整数 pow
,例如用平方的幂,请参阅:
然后将结果转换回整数,因此
floor
(仅使用a
)round
(增加a
如果b>32767
)
为了避免循环,只需将功率平方成几行复制粘贴行(每个位一个)。
顺便说一句,如果你意识到你乘以:
,这可以用+,<<
来完成
1.01dec = 1.0000001010001111 bin
所以你可以为每个二进制 1
而不是 mul
做 shift
和 add
以防 mul
是一个问题...