作者 | 主题 |
---|---|
锋言锋语 至圣 经验值:23511 发帖数:3323 精华帖:51 |
楼主 2020-09-20 15:56:00
主题:浮点数累积处理方法分享 有人说浮点数累计是一个工人的难题, 这个, 由于先天不足, 这个问题确实存在。但是, 为什么不避开这个问题呢? 长话短说, 思路如下: 浮点数float累计, 可以另存整取, 转化为整数累计, 一个DWORD, 可以存储40亿,大多数场合已经足够。如果遇到变态的需求,比如手要求20位有整数数字, 这个方法放后面来说: 简单来说, 就是另存整取。 如果当前累计变量大于1, 就把整数部分提取到 整数计数器中, 小数部分单独计算, 可以设置个阈值, 小数部分累计大于多少时, 提出整数,剩下的继续累积。我用c语言表示如下: void Sum(float v, int *psumInt, float *ptail, int lv) { int a = floor(v); // 取出整数部分; float t = *ptail; *psumInt += a; t += (v - a);
if(t > lv) //大于阈值 { a = floor(t); *psumInt += a; *ptail = t - a; } } 上位机显示时, 可以脚本显示, 直接转换成字符串, 不丢失精度, 如果嫌麻烦, 可以plc直接求和。 2.再说变态需求, 比如20位精度,小数部分处理同上, 整数部分, 可以自己实现一个 增强型加法器,程序如下, c语言实现, 仅供参考 #include <stdio.h> int p[5] = { 0}; //每个int存放四位十进制小数;4 * 5 = 20; void LargeAdd(int *p, int v) //简单示意, 没考虑内存安全, 和v>MaxInt; { int i = 0; p[0] += v; //低四位相加
for(i = 0; i != 4; ++i) //最高的不再进位, 默认不超过20位 { if(p[i] >= 10000) //加法进位, 小学知识 {
p[i + 1] += p[i] / 10000; //整除 p[i] %= 10000; //求余 } } } int main() { for(int i = 1; i <= 2000; ++i) {
LargeAdd(p, i);
printf("%d: ", i); for(int j = 0; j != 5; ++j) { printf("%04d", p[4 - j]);
} printf("\n"); }
} 如上, 任意位数的累加都可以实现; 所以, 也许浮点数累加有问题, 但是累加绝无问题。 办法总比困难多。
不忘初心
|