int和long long类型只能保存整数。虽然整数类型应用的十分广泛。但是在日常生活中,我们还会经常遇到需要表示小数的情况,比如计算圆的面积、物体的重量等。在 C++中,我们可以使用float和 double 类型变量来存储这些小数。float被称为单精度浮点型,而double被称为双精度浮点型。通过名字可以看出来double类型表示的范围和精度都要比float类型高。double类型是C++的默认类型。比如在某个表达式中有一个常量7.0,他会被系统默认为是double类型而不是float类型。
1.浮点型变量的定义
double pi;
也可以定义时直接初始化,比如:
double pi = 3.1415;
2.浮点型数据的使用
与int类型的使用方法一样,既可以通过赋值语句来对浮点型变量赋值,也可以使用cin通过控制台来对赋值。比如:
double r;
r = 1.0;
或
cin>>r;
3.用浮点型对整型的赋值
由于浮点型变量是有整数部分和小数部分共同构成的,而整型变量只能保存整数部分。因此,当用一个浮点型的(常)变量对一个整型变量赋值时,浮点型变量的小数部分会被直接截断(不进行四舍五入操作),只把整数部分赋值给整型变量。例如:
double r = 3.99;
int a;
a = r;
cout<<a<<endl; //输出结果为3,不是4
例1:输入一个浮点型数据,输出该数的整数部分。参考代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
double x;
int a;
cin >> x;
a = x;//获取x的整数部分
cout << a << endl;
return 0;
}
例2:输入一个浮点型数据,输出该数的小数部分。参考代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
double x, b;
int a;
cin >> x;
a = x;//获取x的整数部分
b = x - a;//减去整数部分就剩下小数部分
cout << b << endl;
return 0;
}
例3:输入一个浮点型数据,四舍五入后输出该数的整数数部分。参考代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
double x, b;
int a;
cin >> x;
a = x + 0.5;//如果x的小数后第一位是大于等于5的数字会自动进位
cout << a << endl;
return 0;
}
4.浮点型数据注意事项
(1)浮点型数据不能参与取余(%)运算。即便,浮点型数据的小数部分是零,浮点型的(常)变量都不能参与取余运算。
(2)任何其他类型的数据与浮点型数据进行运算时,其他数据都会先自行“升级”成浮点型行数据后再计算。最后的结果也会是浮点类型。因此,下面三个表达式的运算结果是不同的:
cout << 5 / 2 << endl;
cout << 5 / 2 * 1.0 << endl;
cout << 1.0 * 5 / 2 << endl;
第一行,两个整数相除,因此结果是“商”,也就是2;
第二行,两个整数相除得到“商”——2。然后乘以双精度浮点型数据1.0,因此最终结果也是2.0。只是cout自动把为零的小数部分忽略了。输出的是2,但类型确实双精度浮点类型;
第三行,1.0和5相乘时,5首先自动升级成5.0(双精度浮点型);然后用5.0除以2,2也自动升级成2.0;最终的结果是2.5。
(3)浮点型数据可以用科学计数法来赋值。例如:
double x = 1.23E-2;
cout << x << endl;
输出结果为:0.0123
(4)由于精度问题,直接比较两个double值是否相等可能会导致意外结果。通常的做法是检查两个值之间的差值是否小于某个小的阈值(epsilon),比如下面的代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
float h = 1.1;
if (h == 1.1)
{
cout << "Yes" << endl;
}
else
{
cout << "No" << endl;
}
return 0;
}
从程序的逻辑上看,if语句中的条件是成立的,因此程序应该输出”Yes”。但运行程序会发现,输出的结果竟然是”No”。这就是浮点型数据表示精度的问题。从数学角度看,0.1及0.1整数倍的数据在二进制中是无限循环小数。因此浮点型变量是无法准确表示的。而1.1这个数据默认是双精度浮点型,因此只要把h的定义类型改为double,程序就会输出”Yes”。
但最正确的比较浮点型数据是否相等的方法应该是设定一个阈值(epsilon),只要两个数据的差值小于这个阈值就认为是相同的数据。例如下面的代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
double EPSILON = 1e-9; //1e-9是10的负九次方的科学计数法
double a = 0.3 + 1e-10;
double b = 0.3;
if (fabs(a - b) < EPSILON)
{
cout << "a == b" << endl;
}
else
{
cout << "a != b" << endl;
}
return 0;
}
(5)在用cout输出double类型数据的时候,如果小数部分超过五位就显示前五位(四舍五入以后)。如果不足五位就显示全部小数部分
(6)double类型可以表示一些特殊值,如正无穷大(INFINITY)、负无穷大(-INFINITY)和非数值(NaN)。这些值在某些运算中可能会出现,需要正确处理,比如:
#include <bits/stdc++.h>
using namespace std;
int main()
{
double w = 1.0 / 0.0;
double x = -1.0 / 0.0;
double y = 0.0 / 0.0;
double z = sqrt(-1.0);
if (w == INFINITY)
cout << "Infinity" << endl;
if (x == -INFINITY)
cout << "-Infinity" << endl;
if (isnan(y))
cout << "NAN" << endl;
if (isnan(z))
cout << "NAN" << endl;
return 0;
}
输出结果为:
Infinity
-Infinity
NAN
NAN