C语言中float和double的精度
来源:互联网 发布:hadoop和云计算 编辑:程序博客网 时间:2024/05/16 19:24
助教给小伙伴们调实验的时候,碰到一个求矩阵面积交的问题,问题如下,并不复杂。
问题描述 平面上有两个矩形,它们的边平行于直角坐标系的X轴或Y轴。对于每个矩形,我们给出它的一对相对顶点的坐标,请你编程算出两个矩形的交的面积。输入格式 输入仅包含两行,每行描述一个矩形。 在每行中,给出矩形的一对相对顶点的坐标,每个点的坐标都用两个绝对值不超过10^7的实数表示。 输出格式 输出仅包含一个实数,为交的面积,保留到小数后两位。 样例输入 1 1 3 3 2 2 4 4 样例输出 1.00我的思路是首先求出两个矩形中心的位置,根据两个矩形中心的位置,结合矩形的长宽(这里实际上用的是长宽的一半),很容易求得矩形相交部分的面积。程序如下:
#include <stdio.h>#include <math.h>int main(){//分别用abcd和a1b1c1d1来接收矩形的相对顶点坐标// double a,b,c,d;// double a1,b1,c1,d1;// // scanf("%lf%lf%lf%lf",&a,&b,&c,&d);// scanf("%lf%lf%lf%lf",&a1,&b1,&c1,&d1);float a,b,c,d;float a1,b1,c1,d1; scanf("%f%f%f%f",&a,&b,&c,&d);scanf("%f%f%f%f",&a1,&b1,&c1,&d1);//x,y和x1,y1分别表示矩形中心的坐标 double x=fabs(c-a)/2.0,y=fabs(d-b)/2.0; double x1=fabs(c1-a1)/2.0,y1=fabs(d1-b1)/2.0;//xx,yy和xx1,yy1分别表示矩形的长宽的一半 double xx=(a+c)/2.0,yy=(b+d)/2.0; double xx1=(a1+c1)/2.0,yy1=(b1+d1)/2.0;//xxx和yyy表示两个矩形中心的横纵距离 double xxx=fabs(xx-xx1),yyy=fabs(yy-yy1); if (x1+x<=xxx || y+y1<=yyy) { printf("%.2f\n",0.000); } else { double height=fabs(y1+y-yyy); double width=fabs(x1+x-xxx);if (height > (y > y1 ? y1*2 : y*2))height=(y > y1 ? y1*2 : y*2);if (width > (x > x1 ? x1*2 : x*2)){width=(x > x1 ? x1*2 : x*2);} printf("%.2lf\n",height*width); } return 0;}结果运行之后,有一组用例总是不过。通过某种不怎么光彩的手段,我知道,那组用例的输入数据如下:
283323.2393 2938832.3994 29838432.38288 983723.828
27783.84384 8793002.2 3995852.3884 2928344.2
没头没脑地把接收输入的变量的类型改成了double,程序如下:
#include <stdio.h>#include <math.h>int main(){//分别用abcd和a1b1c1d1来接收矩形的相对顶点坐标 double a,b,c,d; double a1,b1,c1,d1; scanf("%lf%lf%lf%lf",&a,&b,&c,&d); scanf("%lf%lf%lf%lf",&a1,&b1,&c1,&d1);// float a,b,c,d;// float a1,b1,c1,d1;// // scanf("%f%f%f%f",&a,&b,&c,&d);// scanf("%f%f%f%f",&a1,&b1,&c1,&d1);//x,y和x1,y1分别表示矩形中心的坐标 double x=fabs(c-a)/2.0,y=fabs(d-b)/2.0; double x1=fabs(c1-a1)/2.0,y1=fabs(d1-b1)/2.0;//xx,yy和xx1,yy1分别表示矩形的长宽的一半 double xx=(a+c)/2.0,yy=(b+d)/2.0; double xx1=(a1+c1)/2.0,yy1=(b1+d1)/2.0;//xxx和yyy表示两个矩形中心的横纵距离 double xxx=fabs(xx-xx1),yyy=fabs(yy-yy1); if (x1+x<=xxx || y+y1<=yyy) { printf("%.2f\n",0.000); } else { double height=fabs(y1+y-yyy); double width=fabs(x1+x-xxx);if (height > (y > y1 ? y1*2 : y*2))height=(y > y1 ? y1*2 : y*2);if (width > (x > x1 ? x1*2 : x*2)){width=(x > x1 ? x1*2 : x*2);} printf("%.2lf\n",height*width); } return 0;}程序居然神奇地过了。于是,想到可能是精度问题,调试了一下,记录下各个变量的值如下:
大致可以看出,float的精度貌似只能到6位有效数字。google到一篇解释double和float精度这个问题的博客,很详细,文章中将32位的float和64位的double如何存储说的很清楚,下面将相关的内容贴在下面。
1、范围
float和double的范围是由指数的位数来决定的。
float的指数位有8位,而double的指数位有11位,分布如下:
float:
1bit(符号位) 8bits(指数位) 23bits(尾数位)
double:
1bit(符号位) 11bits(指数位) 52bits(尾数位)
于是,float的指数范围为-127~+128,而double的指数范围为-1023~+1024,并且指数位是按补码的形式来划分的。
其中负指数决定了浮点数所能表达的绝对值最小的非零数;而正指数决定了浮点数所能表达的绝对值最大的数,也即决定了浮点数的取值范围。
float的范围为-2^128 ~ +2^128,也即-3.40E+38 ~ +3.40E+38;double的范围为-2^1024 ~ +2^1024,也即-1.79E+308 ~ +1.79E+308。
2、精度
float和double的精度是由尾数的位数来决定的。浮点数在内存中是按科学计数法来存储的,其整数部分始终是一个隐含着的“1”,由于它是不变的,故不能对精度造成影响。
float:2^23 = 8388608,一共七位,这意味着最多能有7位有效数字,但绝对能保证的为6位,也即float的精度为6~7位有效数字;
double:2^52 = 4503599627370496,一共16位,同理,double的精度为15~16位。
ok,说明白了吧。
参考:
http://www.cnblogs.com/BradMiller/archive/2010/11/25/1887945.html
- C语言中float和double的精度
- float 和 double 的精度
- 精确计算java中float和double的精度
- JAVA中控制double和float的精度
- C语言中关于float、double、long double精度及数值范围理解
- C语言中关于float、double、long double精度及数值范围理解
- C语言中关于float、double、long double精度及数值范围理解
- C语言中关于float、double、long double精度及数值范围理解
- Java中float和double精度
- float和double的范围和精度
- float和double的范围和精度
- float和double的范围和精度
- float和double的范围和精度
- float 和 double的精度和范围
- float和double的范围和精度
- double 和float的范围和精度
- java中float,double的精度问题
- 关于float和double的精度问题
- 随笔
- Win32汇编--开始了解窗口程序
- #define、const、typedef的区别
- Google 高级搜索
- Vector用法(C++ Primer中文版)
- C语言中float和double的精度
- java集合总结
- 如何理解c和c ++的复杂类型声明
- php学习之日期与时间库
- Visual C++常用数据类型转换详解
- 第十三章 带参方法 上机练习4 模拟账户查询,实现取款取款
- 我在Github上安家啦!
- RtlZeroMemory中的Rtl是什么意思
- [纠错]fatal error C1853: 'Debug/Park.pch' is not a precompiled header file created