在 for 循环中递增期间的 C++ 双怪异行为
C++ double wierd behaviour during incrementing in for loop
当我注意到这一点时,我正在制作进度条,在 for 循环中递增双精度数时发生了一些奇怪的事情。
编辑: 我不是在问为什么浮点数被破坏了!!我的问题是 for
循环在情况 1 中迭代了一次额外的时间,在情况 4 中迭代了少一次!
我创建了 4 个测试用例。请看下面的代码:-
#include <iostream>
using namespace std;
int main()
{
cout << endl << "Should End on 0.9 :-" << endl; // Abnormal
for (double i = 0 ; i < 1 ; i += 0.1) cout << i << endl;
cout << endl << "Should End on 1 :-" << endl;
for (double i = 0 ; i <= 1 ; i += 0.1) cout << i << endl;
cout << endl << "Should End on 0.99 :-" << endl;
for (double i = 0 ; i < 1 ; i += 0.01) cout << i << endl;
cout << endl << "Should End on 1 :-" << endl; // Abnormal
for (double i = 0 ; i <= 1 ; i += 0.01) cout << i << endl;
}
输出:-
Should End on 0.9 :-
0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1
Should End on 1 :-
0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1
Should End on 0.99 :-
0
0.01
0.02
0.03
0.04
0.05
0.06
0.07
0.08
0.09
0.1
0.11
0.12
0.13
0.14
0.15
0.16
0.17
0.18
0.19
0.2
0.21
0.22
0.23
0.24
0.25
0.26
0.27
0.28
0.29
0.3
0.31
0.32
0.33
0.34
0.35
0.36
0.37
0.38
0.39
0.4
0.41
0.42
0.43
0.44
0.45
0.46
0.47
0.48
0.49
0.5
0.51
0.52
0.53
0.54
0.55
0.56
0.57
0.58
0.59
0.6
0.61
0.62
0.63
0.64
0.65
0.66
0.67
0.68
0.69
0.7
0.71
0.72
0.73
0.74
0.75
0.76
0.77
0.78
0.79
0.8
0.81
0.82
0.83
0.84
0.85
0.86
0.87
0.88
0.89
0.9
0.91
0.92
0.93
0.94
0.95
0.96
0.97
0.98
0.99
Should End on 1 :-
0
0.01
0.02
0.03
0.04
0.05
0.06
0.07
0.08
0.09
0.1
0.11
0.12
0.13
0.14
0.15
0.16
0.17
0.18
0.19
0.2
0.21
0.22
0.23
0.24
0.25
0.26
0.27
0.28
0.29
0.3
0.31
0.32
0.33
0.34
0.35
0.36
0.37
0.38
0.39
0.4
0.41
0.42
0.43
0.44
0.45
0.46
0.47
0.48
0.49
0.5
0.51
0.52
0.53
0.54
0.55
0.56
0.57
0.58
0.59
0.6
0.61
0.62
0.63
0.64
0.65
0.66
0.67
0.68
0.69
0.7
0.71
0.72
0.73
0.74
0.75
0.76
0.77
0.78
0.79
0.8
0.81
0.82
0.83
0.84
0.85
0.86
0.87
0.88
0.89
0.9
0.91
0.92
0.93
0.94
0.95
0.96
0.97
0.98
0.99
[Program finished]
第一个案例应该在 0.9
结束,但它在 1
结束
第 4 种情况应该在 1
结束,但它在 0.99
结束
第二个和第三个案例工作正常。
知道这里发生了什么吗?
我做错了什么?
我在 aarch64 上使用 Clang 编译器 cpu。
答案是浮点数“损坏”了——或者至少不信任精确值。
在循环1中,当它意外打印出1.0时,实际值稍微少了一点(0.999...),所以检查它小于1仍然为真。
在循环 4 中,当您期望它打印 1.0 时,实际值略高(1.0001 或其他),因此检查 <= 1 失败。
当我注意到这一点时,我正在制作进度条,在 for 循环中递增双精度数时发生了一些奇怪的事情。
编辑: 我不是在问为什么浮点数被破坏了!!我的问题是 for
循环在情况 1 中迭代了一次额外的时间,在情况 4 中迭代了少一次!
我创建了 4 个测试用例。请看下面的代码:-
#include <iostream>
using namespace std;
int main()
{
cout << endl << "Should End on 0.9 :-" << endl; // Abnormal
for (double i = 0 ; i < 1 ; i += 0.1) cout << i << endl;
cout << endl << "Should End on 1 :-" << endl;
for (double i = 0 ; i <= 1 ; i += 0.1) cout << i << endl;
cout << endl << "Should End on 0.99 :-" << endl;
for (double i = 0 ; i < 1 ; i += 0.01) cout << i << endl;
cout << endl << "Should End on 1 :-" << endl; // Abnormal
for (double i = 0 ; i <= 1 ; i += 0.01) cout << i << endl;
}
输出:-
Should End on 0.9 :-
0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1
Should End on 1 :-
0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1
Should End on 0.99 :-
0
0.01
0.02
0.03
0.04
0.05
0.06
0.07
0.08
0.09
0.1
0.11
0.12
0.13
0.14
0.15
0.16
0.17
0.18
0.19
0.2
0.21
0.22
0.23
0.24
0.25
0.26
0.27
0.28
0.29
0.3
0.31
0.32
0.33
0.34
0.35
0.36
0.37
0.38
0.39
0.4
0.41
0.42
0.43
0.44
0.45
0.46
0.47
0.48
0.49
0.5
0.51
0.52
0.53
0.54
0.55
0.56
0.57
0.58
0.59
0.6
0.61
0.62
0.63
0.64
0.65
0.66
0.67
0.68
0.69
0.7
0.71
0.72
0.73
0.74
0.75
0.76
0.77
0.78
0.79
0.8
0.81
0.82
0.83
0.84
0.85
0.86
0.87
0.88
0.89
0.9
0.91
0.92
0.93
0.94
0.95
0.96
0.97
0.98
0.99
Should End on 1 :-
0
0.01
0.02
0.03
0.04
0.05
0.06
0.07
0.08
0.09
0.1
0.11
0.12
0.13
0.14
0.15
0.16
0.17
0.18
0.19
0.2
0.21
0.22
0.23
0.24
0.25
0.26
0.27
0.28
0.29
0.3
0.31
0.32
0.33
0.34
0.35
0.36
0.37
0.38
0.39
0.4
0.41
0.42
0.43
0.44
0.45
0.46
0.47
0.48
0.49
0.5
0.51
0.52
0.53
0.54
0.55
0.56
0.57
0.58
0.59
0.6
0.61
0.62
0.63
0.64
0.65
0.66
0.67
0.68
0.69
0.7
0.71
0.72
0.73
0.74
0.75
0.76
0.77
0.78
0.79
0.8
0.81
0.82
0.83
0.84
0.85
0.86
0.87
0.88
0.89
0.9
0.91
0.92
0.93
0.94
0.95
0.96
0.97
0.98
0.99
[Program finished]
第一个案例应该在 0.9
结束,但它在 1
第 4 种情况应该在 1
结束,但它在 0.99
第二个和第三个案例工作正常。
知道这里发生了什么吗? 我做错了什么?
我在 aarch64 上使用 Clang 编译器 cpu。
答案是浮点数“损坏”了——或者至少不信任精确值。
在循环1中,当它意外打印出1.0时,实际值稍微少了一点(0.999...),所以检查它小于1仍然为真。
在循环 4 中,当您期望它打印 1.0 时,实际值略高(1.0001 或其他),因此检查 <= 1 失败。