Проверьте, является ли переданный двойной аргумент «достаточно близким» считаться неотъемлемой

Я работаю над кодом, где мне нужно проверить, действительно ли определенная переменная, которая может принимать двойное значение, принимает целочисленное значение. Я считаю, что двойная переменная принимает целочисленное значение, если оно находится в пределах допуска целого числа. Этот допуск составляет 1е-5.

Вот мой код:

#define SMALL 1e-5
//Double that attains this is considered non zero. Strictly Less than this is 0

int check_if_integer(double arg){
//returns 1 if arg is close enough to an integer
//returns 0 otherwise
if(arg - (int)arg >= SMALL){
if(arg + SMALL > (int)(arg+1.0)){
return(1);
//Code should have reached this point since
//arg + SMALL is 16.00001
//while (int)(arg+1.0) should be 16
//But the code seems to evaluate (int)(arg+1.0) to be 17
}
}
else{
return(1);
}
return(0);
}

int main(void){

int a = check_if_integer(15.999999999999998);

}

К сожалению, при передаче аргумента 15.999999999999998 функция возвращает 0. То есть она считает аргумент дробным, в то время как ей следовало бы вернуть 1, указывающий, что аргумент «достаточно близок» к 16.

Я использую VS2010 Professional.

Любые указатели будут с благодарностью!

0

Решение

Да, с плавающей запятой сложно. Просто так 15.999999999999998 < 16.0это не значит 15.999999999999998 + 1.0 < 17.0, Предположим, у вас есть десятичный тип с плавающей запятой с тремя цифрами точности. Какой результат вы получаете за 9.99 + 1.0 в точности этого типа? Математический результат будет 10.99и округляется до точности этого типа дает 11.0, Двоичная с плавающей точкой имеет ту же проблему.

В этом конкретном случае вы можете изменить (int)(arg+1.0) в (int)arg+1, (int)arg является точным, как и целочисленное сложение.

2

Другие решения

В дополнение к ответу HVD относительно типов; также нецелесообразно добавлять / вычитать маленькие двойники к / из больших двойников из-за способа их внутреннего представления.

Простая работа, которая позволяет избежать обеих проблем:

if (abs(arg - round(arg)) <= SMALL) {
return (1);
} else {
return (0);
}
2

По вопросам рекламы [email protected]