浮点数和双精度值的异常行为
Float是 32 位 IEEE 754 单精度浮点数 1 位表示符号,(8 位表示指数,23* 表示值),即 float 有 7 位十进制数的精度。
Double是 64 位 IEEE 754 双精度浮点数(符号 1 位,指数 11 位,值 52* 位),即 double 具有 15 位十进制精度。
本文重点讨论浮点和双精度值的异常行为。
方案一:
C
// C program to illustrate the abnormal
// behaviours of floating point value
#include
// Driver Code
int main()
{
float f = 0.2;
if (f == 0.2)
printf("it's geek time");
else if (f < 0.2)
printf("it's party time");
else
printf("it's movie time");
return 0;
}
C++
// C++ program to illustrate the abnormal
// behaviours of floating point value
#include
using namespace std;
// Driver Code
int main()
{
float f = 0.2;
if (f == 0.2)
cout << "it's geek time";
else if (f < 0.2)
cout << "it's party time";
else
cout << "it's movie time";
return 0;
}
C
// C program to illustrate the above idea
#include
// Driver Code
int main()
{
// Declare as double or long double
// or long double f = 0.2;
double f = 0.2;
if (f == 0.2)
printf("it's geek time");
else if (f < 0.2)
printf("it's party time");
else
printf("it's movie time");
return 0;
}
C++
// C program to illustrate the above idea
#include
using namespace std;
// Driver Code
int main()
{
// Declare as double or long double
// or long double f = 0.2;
double f = 0.2;
if (f == 0.2)
cout << "it's geek time";
else if (f < 0.2)
cout << "it's party time";
else
cout << "it's movie time";
return 0;
}
C
// C program to illustrate the above idea
#include
// Driver Code
int main()
{
float f = 0.2;
// Typecast 0.2 as a float
if (f == (float)0.2)
printf("it's geek time");
else if (f < (float)0.2)
printf("it's party time");
else
printf("it's movie time");
return 0;
}
C++
// C++ program to illustrate the above idea
#include
using namespace std;
// Driver Code
int main()
{
float f = 0.2;
// Typecast 0.2 as a float
if (f == (float)0.2)
cout << "it's geek time";
else if (f < 0.2)
cout << "it's party time";
else
cout << "it's movie time";
return 0;
}
C
// C program to illustrate the above idea
#include
// Driver Code
int main()
{
float f = 0.2;
// Replace 0.2 with 0.2f
if (f == 0.2f)
printf("it's geek time");
else if (f < 0.2f)
printf("it's party time");
else
printf("it's movie time");
return 0;
}
C++
// C++ program to illustrate the above idea
#include
using namespace std;
// Driver Code
int main()
{
float f = 0.2;
// Replace 0.2 with 0.2f
if (f == 0.2f)
cout << "it's geek time";
else if (f < 0.2)
cout << "it's party time";
else
cout << "it's movie time";
return 0;
}
C
// C program to illustrate the above idea
#include
#include
// Driver Code
int main()
{
float f = 0.2;
// Declare a variable with very small value
// float acceptableDifference = 1e-9;
float acceptableDifference = 0.00000001;
// Check if the diff of both values is
// less than this variable
if (abs(f - 0.2) < acceptableDifference)
printf("it's geek time");
else if (f < 0.2)
printf("it's party time");
else
printf("it's movie time");
return 0;
}
C++
// C++ program to illustrate the above idea
#include
using namespace std;
// Driver Code
int main()
{
float f = 0.2;
// Declare a variable with very small value
// float acceptableDifference = 1e-9;
float acceptableDifference = 0.00000001;
// Check if the diff of both values is
// less than this variable
if (abs(f - 0.2) < acceptableDifference)
cout << "it's geek time";
else if (f < 0.2)
cout << "it's party time";
else
cout << "it's movie time";
return 0;
}
it's movie time
说明:在上面的程序中,输出是“现在是电影时间”而不是“这是极客时间”。所以这里是解释,因为 f 是一个浮点值,'0.2' 是一个双精度值,所以由于两种数据类型的精度差异,可以看到这种异常行为。在语句中,如果(f==0.2), f 正在与 0.2 进行比较,因此在内部它是这样写的:
if((double)(float)(0.2) == (0.2))
由于 0.2 是在上述行中声明和分配时第一次转换为浮点数(因此精度降低并且在发生某些值和某些信息/精度丢失后四舍五入),然后再次转换为双精度在 if 语句中,但无法取回丢失的值。因此,可以看到这种行为。
为了更清楚地理解,让我们以基数为 10 的数字系统为例(类比)。
让我们取 10/3 并将其表示为 5 个有效数字:3.3333 或 3.3334(在四舍五入的情况下)。那就是“浮动”f。现在将f的值转换为具有 8 位有效数字的值(f 为“double”)- 3.3333000 或 3.3334000(在四舍五入的情况下)。那不等于 3.3333333(10/3 的值直接作为双精度数)。
避免异常行为的方法:
在声明/初始化变量时,用 double f = 0.2 或 long double f = 0.2 替换 float f = 0.2:
下面是用于说明上述想法的 C/C++ 程序:
C
// C program to illustrate the above idea
#include
// Driver Code
int main()
{
// Declare as double or long double
// or long double f = 0.2;
double f = 0.2;
if (f == 0.2)
printf("it's geek time");
else if (f < 0.2)
printf("it's party time");
else
printf("it's movie time");
return 0;
}
C++
// C program to illustrate the above idea
#include
using namespace std;
// Driver Code
int main()
{
// Declare as double or long double
// or long double f = 0.2;
double f = 0.2;
if (f == 0.2)
cout << "it's geek time";
else if (f < 0.2)
cout << "it's party time";
else
cout << "it's movie time";
return 0;
}
it's geek time
0.2强制转换为float,而if语句里面比较:
下面是用于说明上述想法的 C/C++ 程序:
C
// C program to illustrate the above idea
#include
// Driver Code
int main()
{
float f = 0.2;
// Typecast 0.2 as a float
if (f == (float)0.2)
printf("it's geek time");
else if (f < (float)0.2)
printf("it's party time");
else
printf("it's movie time");
return 0;
}
C++
// C++ program to illustrate the above idea
#include
using namespace std;
// Driver Code
int main()
{
float f = 0.2;
// Typecast 0.2 as a float
if (f == (float)0.2)
cout << "it's geek time";
else if (f < 0.2)
cout << "it's party time";
else
cout << "it's movie time";
return 0;
}
it's geek time
将 0.2 写为浮点值:
下面是用于说明上述想法的 C/C++ 程序:
C
// C program to illustrate the above idea
#include
// Driver Code
int main()
{
float f = 0.2;
// Replace 0.2 with 0.2f
if (f == 0.2f)
printf("it's geek time");
else if (f < 0.2f)
printf("it's party time");
else
printf("it's movie time");
return 0;
}
C++
// C++ program to illustrate the above idea
#include
using namespace std;
// Driver Code
int main()
{
float f = 0.2;
// Replace 0.2 with 0.2f
if (f == 0.2f)
cout << "it's geek time";
else if (f < 0.2)
cout << "it's party time";
else
cout << "it's movie time";
return 0;
}
it's geek time
通过声明一个acceptableDifference变量来检查两个值之间的差异是否非常小(1e-9):
下面是用于说明上述想法的 C/C++ 程序:
C
// C program to illustrate the above idea
#include
#include
// Driver Code
int main()
{
float f = 0.2;
// Declare a variable with very small value
// float acceptableDifference = 1e-9;
float acceptableDifference = 0.00000001;
// Check if the diff of both values is
// less than this variable
if (abs(f - 0.2) < acceptableDifference)
printf("it's geek time");
else if (f < 0.2)
printf("it's party time");
else
printf("it's movie time");
return 0;
}
C++
// C++ program to illustrate the above idea
#include
using namespace std;
// Driver Code
int main()
{
float f = 0.2;
// Declare a variable with very small value
// float acceptableDifference = 1e-9;
float acceptableDifference = 0.00000001;
// Check if the diff of both values is
// less than this variable
if (abs(f - 0.2) < acceptableDifference)
cout << "it's geek time";
else if (f < 0.2)
cout << "it's party time";
else
cout << "it's movie time";
return 0;
}
it's geek time
注意:当不需要更改程序中任何位置的任何变量的数据类型时,首选最后一种方法,否则也可以遵循上述列出的任何方法,因为它们简单、简短且不那么复杂。在比较 if 语句中的浮点数时要格外小心和小心。
想要从精选的视频和练习题中学习,请查看 C 基础到高级C 基础课程。