- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我有一个定点类 (10.22),我需要一个 pow、一个 sqrt、一个 exp 和一个 log 函数。
唉,我什至不知道从哪里开始。谁能给我一些有用文章的链接,或者更好的是,给我一些代码?
我假设一旦我有了一个 exp 函数,那么实现 pow 和 sqrt 就变得相对容易了。
pow( x, y ) => exp( y * log( x ) )
sqrt( x ) => pow( x, 0.5 )
我发现困难的只是那些 exp 和 log 函数(好像我记得我的一些日志规则,但我记不起关于它们的更多内容)。
据推测,sqrt 和 pow 也会有一种更快的方法,因此即使它只是说使用我上面概述的方法,也将不胜感激这方面的任何指针。
请注意:这必须是跨平台和纯 C/C++ 代码,所以我不能使用任何汇编程序优化。
最佳答案
一个非常简单的解决方案是使用合适的表驱动近似值。如果您正确减少输入,您实际上并不需要大量数据。 exp(a)==exp(a/2)*exp(a/2)
,这意味着你真的只需要计算exp(x)
对于 1 < x < 2
.在该范围内,runga-kutta 近似值将给出合理的结果,大约 16 个 IIRC 条目。
同样,sqrt(a) == 2 * sqrt(a/4) == sqrt(4*a) / 2
这意味着您只需要 1 < a < 4
的表条目. Log(a) 有点难:log(a) == 1 + log(a/e)
.这是一个相当慢的迭代,但 log(1024) 只有 6.9,所以你不会有很多迭代。
您可以对 pow 使用类似的“整数优先”算法:pow(x,y)==pow(x, floor(y)) * pow(x, frac(y))
.这是因为 pow(double, int)
是微不足道的(分而治之)。
[编辑] 对于 log(a)
的整数部分, 存储表 1, e, e^2, e^3, e^4, e^5, e^6, e^7
可能很有用所以你可以减少log(a) == n + log(a/e^n)
通过对该表中的 a 进行简单的硬编码二进制搜索。从 7 步到 3 步的改进不是很大,但这意味着您只需除以一次 e^n
而不是 n
次 e
.
[编辑 2]最后log(a/e^n)
术语,您可以使用 log(a/e^n) = log((a/e^n)^8)/8
- 每次迭代
通过表查找
产生更多的3位。这使您的代码和表格大小保持较小。这通常是嵌入式系统的代码,它们没有大缓存。
[编辑 3]这对我来说仍然不聪明。 log(a) = log(2) + log(a/2)
.您可以只存储定点值log2=0.6931471805599
,计算前导零的个数,移位a
进入用于查找表的范围,并将该移位(整数)乘以定点常数 log2
.可以低至 3 条指令。
使用 e
因为减少步骤只是给你一个“好”log(e)=1.0
不变,但这是错误的优化。 0.6931471805599 和 1.0 一样好;两者都是 10.22 定点的 32 位常量。使用 2 作为常数来缩小范围允许您使用位移位进行除法。
[编辑 5]而且由于您将其存储在 Q10.22 中,因此您可以更好地存储 log(65536)=11.09035488。 (16 x 对数 (2))。 “x16”意味着我们还有 4 位可用的精度。
您仍然可以从编辑 2 中获得诀窍,log(a/2^n) = log((a/2^n)^8)/8
.基本上,这会给你一个结果(a + b/8 + c/64 + d/512) * 0.6931471805599
- b,c,d 在 [0,7] 范围内。 a.bcd
真的是一个八进制数。毫不奇怪,因为我们使用 8 作为电源。 (这个技巧同样适用于 2、4 或 16 次方。)
[编辑 4]仍然有一个开放的结局。 pow(x, frac(y)
只是 pow(sqrt(x), 2 * frac(y))
我们有一个不错的1/sqrt(x)
.这为我们提供了更有效的方法。说frac(y)=0.101
二进制,即 1/2 加 1/8。那么这意味着x^0.101
是 (x^1/2 * x^1/8)
.但是x^1/2
只是 sqrt(x)
和 x^1/8
是 (sqrt(sqrt(sqrt(x)))
.再保存一项操作,Newton-Raphson NR(x)
给我们1/sqrt(x)
所以我们计算1.0/(NR(x)*NR((NR(NR(x)))
.我们只反转最终结果,不要直接使用 sqrt 函数。
关于c++ - 快速定点 pow、log、exp 和 sqrt,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4657468/
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 9 年前。 Improv
我发现了 pow(x, n) 的迭代实现,它需要 o(log n) 时间和常量空间,如下所示: double pow(double x, int n) { double left = x;
我想创建一个特征,说它实现了num_traits::pow::Pow - Rust。 我的特征当前定义为: pub trait PrimeSieveTrait: AddAssign + MulAs
对于我的项目,我应该在 java 中创建一个图形计算器(绘制图形),并以函数作为输入。我已经找到了一种正确绘制函数图的方法。但是我想不出一种方法可以让解释器理解该功能。如果我能够做到这一点,以便我可以
我发现对于大整数,math.pow() 没有成功给出它的整数版本。 (我在使用 math.pow 实现时遇到了一个错误 Karatsuba multiplication)。 例如: >>> a_Siz
问题或多或少说明了一切。 calling a host function("std::pow ") from a __device__/__global__ function("_calc_psd")
我想知道,因为当我在检查模式下运行我的代码时,似乎出现了一些差异。例如: List getFactors(int n) { List factors = [[1, n]]; doubl
pow(a/b,x) 和 pow(b/a,-x) 在精度上有区别吗?如果存在,将小于 1 的数字提升为正幂或将大于 1 的数字提升为负幂会产生更准确的结果吗? 编辑:让我们假设 x86_64 处理器和
此代码在 Windows 上的 Visual Studio 2010 上正确编译,但我在 Linux、g++ 上遇到此错误。谁能解释一下如何解决这个问题? int bits; T scale; std
Python内置的pow(x, y)(没有第三个参数)返回的结果和math.pow()返回的值有区别吗>,在两个 float 参数的情况下。 我问这个问题是因为 documentation对于 mat
这个问题在这里已经有了答案: Why was std::pow(double, int) removed from C++11? (1 个回答) 关闭 9 年前。 在 C++ 03 中,使用例如st
我可以将pow()与#include 一起使用,而无需使用using关键字或::运算符。为什么? 最佳答案 来自标准的[headers]/4。 Except as noted in Clause 20
我觉得这很有趣: System.out.println( (long)(Math.pow(2,63) - 1) == Long.MAX_VALUE); // true System.out.prin
这个打印 100: int j=2; int i= pow(10,2); printf("%d\n", i); 这个打印出 99: int j=2; int i= pow(10,j); print
这也是一个与数学相关的问题,但我想用 C++ 实现它...所以,我有一个 2^n 形式的数字,我必须计算它的数字总和(以 10 为基数;P)。我的想法是用下面的公式来计算: sum = (2^n mo
我看到这个关于 std::pow 的老问题:What is more efficient? Using pow to square or just multiply it with itself? 旧
我正在尝试比较 pow(x,2.0) 和 pow(x,2.0000001) 的性能,但我认为 2.0 会快得多,但它们的速度相同。我什至通过使用 -Xint 参数运行 jar 来删除 JIT 优化。
我的 linux 版本是 4.19.0-6-amd64 #1 SMP Debian 4.19.67-2+deb10u1 (2019-09-20) x86_64 GNU/Linux我的 gcc 版本是
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 6 年前。 Improve t
python3 中的 pow() 函数提供指数的值。 >>>pow(2,3) 8 Python3 支持负指数,即 可以使用 pow(10,-1) 表示。当我计算 pow(4,-1,5) 时,它给出了输
我是一名优秀的程序员,十分优秀!