Проверка, является ли float целым числом


Как я могу проверить, если a float переменная содержит целое значение? До сих пор я использовал:

float f = 4.5886;
if (f-(int)f == 0)
     printf("yesn");
else printf("non");

но мне интересно, есть ли лучшее решение, или если у этого есть какие-либо (или многие) недостатки.

8 56

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.

if (fmod(f, 1) == 0.0) {
  ...
}

не забудьте math.h и libm.

if (f <= LONG_MIN || f >= LONG_MAX || f == (long)f) /* it's an integer */

Я не уверен на 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/