Проверка, является ли float целым числом
Как я могу проверить, если a float
переменная содержит целое значение? До сих пор я использовал:
float f = 4.5886;
if (f-(int)f == 0)
printf("yesn");
else printf("non");
но мне интересно, есть ли лучшее решение, или если у этого есть какие-либо (или многие) недостатки.
8 ответов:
помимо прекрасных ответов уже даны, вы также можете использовать
ceilf(f) == f
илиfloorf(f) == f
. Оба выражения возвращаютtrue
Еслиf
- целое число. Они тоже возвращаютсяfalse
для NaNs (NaNs всегда сравнивают неравные) иtrue
для ±бесконечности, и не имеют проблемы с переполнением целочисленного типа, используемого для хранения усеченного результата, потому чтоfloorf()
/ceilf()
возвращениеfloat
s.
имейте в виду, что большинство методов здесь действительны, предполагая, что ошибка округления из-за предыдущих расчетов не является фактором. Например, вы может использовать
roundf
, например:float z = 1.0f; if (roundf(z) == z) { printf("integer\n"); } else { printf("fraction\n"); }
проблема с этим и другими подобными методами (например,
ceilf
, кастингlong
и т. д.) заключается в том, что, хотя они отлично работают для целых числовых констант, они потерпят неудачу, если число является результатом вычисления, которое было подвержено ошибке округления с плавающей запятой. Для пример:float z = powf(powf(3.0f, 0.05f), 20.0f); if (roundf(z) == z) { printf("integer\n"); } else { printf("fraction\n"); }
печатает "дробь", хотя (31/20)20 должно быть равно 3, потому что фактический результат расчета оказался 2.9999992847442626953125.
любой подобный метод, будь то
fmodf
или что-то еще, подчиняется этому. В приложениях, которые выполняют сложные или склонные к округлению вычисления, обычно то, что вы хотите сделать, это определить некоторое значение " допуска "для того, что составляет" целое число " (это касается сравнения равенства с плавающей запятой в целом). Мы часто называем это толерантностью Эпсилон. Например, допустим, что мы простим компьютеру ошибку округления до + / - 0.00001. Тогда, если мы тестируемz
, мы можем выбрать Эпсилон 0,00001 и сделать:if (fabsf(roundf(z) - z) <= 0.00001f) { printf("integer\n"); } else { printf("fraction\n"); }
вы действительно не хотите использовать
ceilf
вот напримерceilf(1.0000001)
это 2 не 1, аceilf(-1.99999999)
не -1, не -2.вы могли бы использовать
rintf
на местеroundf
Если вы предпочитать.выберите значение допуска, которое подходит для вашего приложения (и да, иногда нулевой допуск подходит). Для получения дополнительной информации, ознакомьтесь с этой статьей на сравнение чисел с плавающей запятой.
stdlib float modf (float x, float *ipart) разбивается на две части, проверьте, если возвращаемое значение (дробная часть) == 0.
Я не уверен на 100%, но когда вы бросаете f в int и вычитаете его из f, я считаю, что он возвращается к поплавку. Это, вероятно, не будет иметь значения в этом случае, но это может представлять проблемы в будущем, если вы ожидаете, что это будет int по какой-то причине.
Я не знаю, если это лучшее решение само по себе, но вы могли бы использовать математику модуля вместо этого, например:
float f = 4.5886; bool isInt; isInt = (f % 1.0 != 0) ? false : true;
в зависимости от вашего компилятора, вы можете или не нужны .0 после 1, все неявные приведения дело вступает в игру. В этом коде bool isInt должен быть true, если справа от десятичной точки все нули, и false в противном случае.
#define twop22 (0x1.0p+22) #define ABS(x) (fabs(x)) #define isFloatInteger(x) ((ABS(x) >= twop22) || (((ABS(x) + twop22) - twop22) == ABS(x)))
Ну я недавно столкнулся с этой проблемой и удивительно dint найти какие-либо решения в интернете для этого. Итак, вот мое решение. Например-если значение 3.00 и нам нужно только 3, то нам нужно проверить, если после ".- есть нули или нет. Если все это может быть преобразовано в int или же он остается float. Так что включите эту функцию
int isInt(float val) { int i = (int) val; if( i != val) return 0; // its not an integer else return 1; // is an integer } int main() { float i = 3.9; // not this is an example. if(isInt()) printf("%d", i); else printf("%f", i); return 0; }
надеюсь, что это помогает!
http://anandkhinvasara.com/check-whether-number-integer-float-c/