int main()
{
float x = k ; // k is some fixed positive value
while(x>0)
x-- ;
return 0 ;
}
Может ли программа выше в бесконечном цикле?
int main()
{
float x = k ; // k is some fixed positive value
while(x>0)
x-- ;
return 0 ;
}
Может ли программа выше в бесконечном цикле?
Да, это возможно. В качестве примера возьмем максимум float.
Как показывает этот код, для самого большого значения float m
, m
равно m - 1
:
#include <iostream>
#include <limits>
int main() {
auto m = std::numeric_limits<float>::max();
auto l = m;
l--;
std::cerr << (m == l) << "\n";
}
Демо: http://ideone.com/Wr9zdN
Следовательно, с этим стартовым значением цикл будет бесконечным.
Почему это?
float
имеет (как и любой другой встроенный тип) ограниченную точность. Чтобы сделать x - 1
представимым числом, отличным от x
, разница между наибольшим числом меньше x
должна быть меньше 2.
Теперь позвольте рассчитать разницу между m
, максимальным поплавком и x
, самым большим поплавком, который строго меньше m
:
#include <iostream>
#include <cmath>
#include <limits>
int main() {
auto m = std::numeric_limits<float>::max();
std::cout << "float max: " << m << "\n";
auto x = std::nextafter(m, 0.0f);
std::cout << "biggest value less than max: " << x << "\n";
auto d = m - x;
std::cout << "the difference: " << d << "\n";
}
Демо: http://ideone.com/VyNgtE
Оказывается, между этими двумя числами существует огромный пробел 2.02824e+31
. Дальше больше 1. 1 просто слишком мало, чтобы иметь значение.
Да, может. Если k
- FLT_MAX
, например. Недостаточно точности для обработки такого малого расстояния между такими большими числами.
#include <float.h>
#include <stdio.h>
int main()
{
float a = FLT_MAX;
float b = a - 1;
printf("%.10f\n", a - b);
return 0;
}
Вывод:
0.0000000000
Я думаю, что это возможно. Если k
достаточно большое округление, вы поглотите свой декремент.