测试网站:C语言在线运行,代码编译测试 – 在线编译器(nhooo.com)
1.循环加数据,误差越来越大:
float a = 99.2f;//float a = 1.3f;float b = 0;for(int i =0; i<1000; i++){b = b + a;}for(int i =0; i<10000; i++){b = b + a;}printf("%f\n", a);printf("---%f\n", b);
输出:
99.199997---99200.695312---991913.875000
1000次的时候还好。
10000次的时候,误差已经到了100。
解决方法:1.转化成整数再运算;在进行大量的浮点数运算时,为了提高运算的速度和准确性,可以考虑将小数转换为整数进行计算,再将结果转换回小数。
2.看看开源代码中C语言的算法是怎么算的;
3.都转成double,这样10000次计算结果是—991999.969482。尽量避免使用float类型。虽然float类型能够节省内存空间,但是其精度不够高,容易导致精度丢失。在精度要求比较高或需要进行复杂计算时,建议使用double类型。
2.比较两个数的大小,必须用一个float.h的宏定义EPS最小误差来定。大概0.000001.精确到6位。
double test=0.1;if(fabs(test-(1-0.9))<0.0001){printf("正常");}else{printf("what!!!");}
3.C语言发送双精度到Java语言,需要精确到前两位发送。具体思路是转换成字符。
float ddd = (float)( (a+0.001)*100) / 100;printf("四舍五入%f\n", ddd);float ff=1024.58;double dd=12345678901234.58;char strff[21],strdd[21];sprintf(strff,"%.2f",ddd);printf("strff=%s\n",strff);// 输出strff=1024.58float e = atof(strff);printf("%f\n", e);
输出
四舍五入99.200996strff=99.2099.199997二进制就是这样,想只显示两位是不可能的!
Java端再调用BigDecimal类型进行计算。在进行精度要求极高的计算时,可以使用Java提供的BigDecimal类型进行计算,它能够保证精度不会损失。不过注意:BigDecimal类型的计算效率较低
1. 由于计算机中浮点数表示的方式为近似值,所以在进行浮点数的比较时,需要使用特定的比较方式,避免误判。例如:Math.abs(a – b) < 0.000001,表示a和b的差值小于0.000001。
2. 在进行除法运算时,需要判断被除数是否为0,避免抛出异常。
3. 浮点数中可能出现的NaN(Not a Number)或Infinity值需要进行特殊处理,否则可能导致程序异常终止。
4.C、Java默认的是double类型,用小数最好不要用 .f ,否则会出现误差
C语言调用 Math.round 将小数四舍五入到整数
float a = 99.4999;
a = round(a);
printf(“%f\n”, a);
5. Java 发送小数到C
//String value of 会丢失精度NumberFormat nf = NumberFormat.getInstance();nf.setGroupingUsed(false);String s1 = nf.format(value);