计算自然对数的快速算法,之需要依赖sqrt,嵌入式设备上可用
在1982年,Tateaki. Sasaki 和 Yasumasa Kanada 发表了一篇论文:Practically Fast Multiple-Precision Evaluation of LOG(x)。在这篇只有四页的论文中,他们介绍了一个计算自然对数的快速算法。
c 代码如下:
#include <math.h> #include <stdio.h> #include <stdlib.h> #define ln10 2.30258509299404568401799145468 #define pi2 6.283185307179586476925286766559 // 1e-14 #define eps2 0.00000000000001 // 1e-28 #define eps1 (eps2 * eps2) float sqrt_tmp(float x) { if (x < 0) return 0; if (x == 0) return 0; float y = (float) sqrtf(x); return (y + x / y) / 2; } float negative_log(float q) { // q in ( 0.01, 0.1 ] int p = 1; float r = q, s = q, n = q, q2 = q * q, q1 = q2 * q; for (p = 1; (n *= q1) > eps1; s += n, q1 *= q2) r += (p = !p) ? n : -n; float u = 1 - 2 * r, v = 1 + 2 * s, t = u / v; float a = 1, b = sqrt_tmp(1 - t * t * t * t); for (; a - b > eps2; b = sqrt_tmp(a * b), a = t) t = (a + b) / 2; return pi2 / (a + b) / v / v; } float logf(float x) { if (x <= 0) return 0; if (x == 1) return 0; int k = 0; for (; x > 0.1; k++) x /= 10; for (; x <= 0.01; k--) x *= 10; return k * ln10 - negative_log(x); } int main(int argc, char *argv[]) { float input; sscanf(argv[1], "%f", &input); float r = logf(input); printf("%f\n", r); return 0; }
总体也不是很耗时间,总共循环才13个。
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
支付宝扫一扫捐赠
支付宝扫一扫捐赠
微信公众号: 共鸣圈
欢迎讨论,邮件: 924948$qq.com 请把$改成@
QQ群:263132197
QQ: 924948