签到有奖
消息提醒
运维工程师专区
官方商城
扫码分享好友 任选多种周边
有人说浮点数累计是一个工人的难题, 这个, 由于先天不足, 这个问题确实存在。但是, 为什么不避开这个问题呢? 长话短说, 思路如下:
浮点数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);
*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");
如上, 任意位数的累加都可以实现;
所以, 也许浮点数累加有问题, 但是累加绝无问题。 办法总比困难多。
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
帖子链接:https://www.ad.siemens.com.cn/club/bbs/post.aspx?a_id=1643251&b_id=5&s_id=0&num=28
你是很喜欢hmi上搞这些东西呀!hmi本身的工作很多,能用plc解决的,就不要用wincc了,wincc很累。这种算法plc中解决的说明已经很多了。
http://www.ad.siemens.com.cn/service/answer/solution.aspx?Q_id=43844&cid=1029
http://www.ad.siemens.com.cn/service/answer/solution.aspx?Q_ID=89047&cid=1029
还有很多就不列举了。
@zhangli0版主, 我说的是如何实现高精度累加,避免浮点大树加小数丢失数据, 不是说简单积分的问题。
而且, 用c语言表示, 不一定是说非得坐在上位机。 我喜欢用c来表达算法, 简单直接。
关于累加, 总逃不掉积分二字。 稍微用点心就该明白原理。 这里不讨论积分, 讨论的是高精度累加。
这是落后的思想。
哪里有什么整数和小数?
理工科的眼里, 所有物理值都应该是科学计数法。 只有一位整数+小数,以及指数。
而事实上计算机里面浮点数的表达方式也是科学计数法表示的。
你这么硬要区分整数加小数, 那遇到根本没有小数全是整数的测量值,怎么算?或者遇到量纲极大, 有效数值在小数点后十几位的怎么算?
科学计数法足矣
感谢分享哦
应用领域不同,各有用途
如果有双精度数,一般来说就够用了。
如果没有,只有单精度,那我直接用整数进行累计,多几个级联,一个整数表示10000,两个就能表示1e8,3个表示1e12,最后显示的时候再转成浮点数
好好学习饿!!!
好好学习吧!现在连浮点数取整都整不明白。
万版主跑偏了, 我们讨论的是高精度累加, 不是其他什么。
你连小数点的位置都不能确定, 怎么跑偏了
跟着大家学习,值得。
引用详细内容:
我不知道你说这个什么意思 ? 有点不知所云。
我不知道你是不是在说我不知道浮点数的格式。
本帖子在讨论高精度累加, 至于浮点数的原理, 我想知道的人不在少数。 请分清主题。 否则我说东,你说西, 先不说谁对谁错, 这样大家费这劲发帖图啥呢?
你确实是不知所云。
你做一个标准块的时候, 实现并不知道来的这个浮点数的小数点在什么位置。 是有1位小数,还是3位小数,整数部分有几位?会不会来的数值压根就在小数点后5-6位?从科学计数来说指数部分是负值?
你总不能说,具体问题具体分析, 遇到啥变量再定吧?
这就是我说的你不知道小数点的位置。 大家都不知道。
不知道小数点位置的情况下, 一厢情愿的切分整数和小数。
这个我同意。
那我的帖子做些修正:
就是输入在合理范围内的高精度累加, 比如正常情况下, 变送器到plc的, 由于16位整数转换, 本身就有个最小分辨率, 会滤除过小的值。 再加上必要的逻辑处理, 比如小流量切除之类的。 这种前提下, 高精度累计没有问题。
实际上,如果不考虑上述条件, 强行分开小数和整数, 虽然理论上没有问题, 但是小数部分累加,仍然会丢失精度。
32位无符号整数表示的范围是0~4 294 967 295,32位实数表示的范围是±3.4e38,很明显实数比整数表示的范围大,如果实数累计后的结果5 000 000 000,再累计你用整数还能表示吗?
我不是提供了两种方案吗? 一种是40亿, 一种是组合实现任意位数
我主要要表达的意思是
1、hmi很累,你就能让它休息就休息吧。
2、plc中实现这种功能前面已经讨论很多,能用plc做的,就不要用hmi了。
3、plc的数据处理效率比hmi高多了,hmi要处理的事情太多了。
4、如果一定要用hmi处理,不是说不行,精度损失你还是无法避免的。
5、不停车的情况下,进行项目更改,存在很大的隐患。生产型企业如果造成损失是很大的,很少有在线改东西的。尽然能停线,那么算法写到plc中是最好的。
分享
扫码分享好友 任选多种好礼
收藏
有帮助
欢迎您访问支持中心!
丰富的视频,全方位的文档,大量的网友交流精华……
为了更好的完善这些内容,我们诚邀您在浏览结束后,花20秒左右的时间,完成一个用户在线调查!
感谢您的支持!
密码至少8位,包含大、小写字母,数字和符号至少三种。
允许邮箱和手机接收来自支持中心网站的信息
我已同意《支持中心网站注册协议和隐私政策》
微信登录扫码一键登录
验证码登录
密码登录
二维码失效点击重试
打开微信扫一扫,快速登录/注册
未注册手机验证后自动登录,注册即代表同意《支持中心网站注册协议和隐私政策》
三日内免验证登录
短信登录
登录