当前位置: 首页 > news >正文

自行实现log2对数运算

在应用中,需要实现以2为底对数运算,通过换底公式,可以将其转化为相对简单的运算,进而实现不同底数的对数运算。

一、数学原理

对数换底公式

对数变换级数

通过换底公式,ln2为常数,所以我们只需要求得ln(x)即可自行实现不同底数的对数运算。

所以我们通过上诉的对数变换级数去进行循环收敛获得一个相对准确的值。

通常适用于不包含数学库或者不支持浮点,要求硬件兼容性强的项目中

二、整形的ln(x)的C语言实现

整形此处因为对精度要求不高,只需要运算后能大致落在结果的附近即可满足设计需求。

下面对代码进行简单说明。


static unsigned int calc_api_lnd(unsigned int x)
{unsigned long long numerator;unsigned int denominator;unsigned long long y;    /* (x-1)*1000/(x+1),整形转化 */unsigned long long y_sq; /* y*y *//* 循环运算 */unsigned long long sum;unsigned long long term;long long k;                       /* 迭代次数 */const unsigned int max_iter = 50;  // 最大迭代次数,防止无限循环const unsigned int min_term = 100; // 终止阈值unsigned int result;               /* 计算结果 */// 输入合法性检查if (x == 0){printf("Invalid input: x cannot be 0");return 0; // 无效输入返回0(可根据需求调整错误码)}if (x == 1){return 0; // ln(1) = 0,直接返回避免无效计算}// 计算缩放后的y值:y = ((x-1)/(x+1)) × 1000(整数近似)numerator = (unsigned long long)(x - 1) * 1000;denominator = x + 1;y = numerator / denominator;// 计算y²/1000(保持缩放比例),避免溢出if (y > 100000) // 过大的y直接计算平方会溢出,提前处理{y_sq = (y / 100) * (y / 100) * 10; // 分阶段计算避免溢出}else{y_sq = (y * y) / 1000;}sum = y;term = y;k = 1;printf("-->term=%lld, sum=%lld, k=%lld, y_sq=%lld", term, sum, k, y_sq);while (term > min_term && k < max_iter){// 检查下一次乘法是否会溢出if (term > ULLONG_MAX / y_sq){printf("Term would overflow, stopping early");break;}// 计算下一项:term = term * y_sq / 1000term *= y_sq;term /= 1000;sum += term / (2 * k + 1);k++;}// 防止最终结果溢出(如果sum过大,截断到合理范围)result = (2 * sum) > UINT_MAX ? UINT_MAX : (unsigned int)(2 * sum);printf("result=%u\r\n", result);return result;
}

三、浮点的ln(x)的C语言实现

因为浮点的不需要对小数部分做缩放处理,所以相对更加简单。代码如下

static double calc_api_lnf(double x)
{double y;double y_squared;double sum;double term;int k;const int max_iter = 100;     // 最大迭代次数const double epsilon = 1e-12; // 精度阈值,控制迭代终止double result;// 输入合法性检查if (x <= 0.0){printf("Invalid input: x must be positive\n");return 0; // 无效输入返回NaN}if (x == 1.0){return 0.0; // ln(1) = 0,直接返回}// 计算核心变量 y = (x-1)/(x+1)y = (x - 1.0) / (x + 1.0);y_squared = y * y; // 预计算y的平方,避免重复计算sum = y;           // 初始项:y^1 / 1term = y;          // 当前项,初始为第一项k = 1;             // 迭代计数器printf("-->term=%.10f, sum=%.10f, k=%d, y_sq=%.10f\n", term, sum, k, y_squared);// 手动判断term的绝对值是否大于epsilonwhile ((term > epsilon || term < -epsilon) && k < max_iter){// 计算下一项:term = term * y² (因为每一项是前一项乘以y²)term *= y_squared;// 分母为2k+1,累加至总和k++;sum += term / (2 * k - 1);}// 最终结果:ln(x) = 2 * sumresult = 2 * sum;// printf("result=%.10f\n", result);return result;
}

http://www.dtcms.com/a/309058.html

相关文章:

  • Pydantic模块学习
  • TDengine 中 TDgp 中添加机器学习模型
  • AT6668B芯片说明书
  • unity学习——视觉小说开发(一)
  • 51单片机入门:模块化编程
  • 用 TensorFlow 1.x 快速找出两幅图的差异 —— 完整实战与逐行解析 -Python程序图片找不同
  • forceStop流程会把对应进程的pendingIntent给cancel掉
  • ceph 14.2.22 nautilus Balancer 数据平衡
  • 通过CISSP考试,共答到第127题
  • 雷达微多普勒特征代表运动中“事物”的运动部件。
  • 机械手弧焊电源气体流量优化方法
  • 算法:分治-快速排序
  • IO流File类的基本使用
  • 前端开发(HTML,CSS,VUE,JS)从入门到精通!第二天(CSS)
  • 《n8n基础教学》第三节:模拟一个自动化场景
  • CSS的2D转换
  • 【Shell脚本自动化编写——报警邮件,检查磁盘,web服务检测】
  • 了解Reddit自动化 社区营销更精准
  • CSS组件化样式新篇章:@scope
  • vi/vim跳转到指定行命令
  • 机器学习第二课之逻辑回归(二)LogisticRegression
  • LSTM网络从浅入深原理级讲解与Pytorch逐行讲解实现
  • [python][selenium] Web UI自动化8种页面元素定位方式
  • K8S周期性备份etcd数据实战案例
  • 番茄项目3:完成了项目的数据库设计
  • npm报错:npm install 出现“npm WARN old lockfile”
  • ZED 2/2i 相机安装与调试完整指南 | Ubuntu 20.04 + CUDA 11.8
  • k8s云原生rook-ceph pvc快照与恢复(下)
  • 前端SWR策略:优化数据请求
  • STM32学习记录--Day5