Я предпочитаю Freemarker, здесь по Скорости; imo, Freemarker, намного более простой в этом случае.
при использовании Spring, тогда можно интересоваться, Freemarker в Spring MVC.
Используйте std :: modf
:
double intpart;
modf(value, &intpart) == 0.0
Не преобразовывать в int
! Число 1.0e + 300
тоже целое, как вы знаете.
Изменить: Как указывает Пит Киркхэм, передача 0 в качестве второго аргумента не гарантируется стандартом для работы, требуя использования фиктивная переменная и, к сожалению, делает код менее элегантным.
Предполагая, что у вас есть библиотека cmath
, вы можете сравнить число с его этажом . Если число может быть отрицательным, сначала убедитесь, что вы получили absolute .
bool double_is_int(double trouble) {
double absolute = abs( trouble );
return absolute == floor(absolute);
}
avakar был почти прав - используйте modf, но детализация была отключена.
modf возвращает дробную часть, поэтому проверка должна состоять в том, что результат modf равен 0,0.
modf принимает два аргумента, второй из которых должен быть указателем того же типа, что и первый аргумент. Передача NULL или 0 вызывает ошибку сегментации в среде выполнения g ++. Стандарт не указывает, что передача 0 безопасна; может случиться так, что он работает на машине авакара, но не делайте этого.
Вы также можете использовать fmod (a, b)
, который вычисляет a
по модулю b
, передавая 1.0. Это тоже должно дать дробную часть.
#include<cmath>
#include<iostream>
int main ()
{
double d1 = 555;
double d2 = 55.343;
double int_part1;
double int_part2;
using namespace std;
cout << boolalpha;
cout << d1 << " " << modf ( d1, &int_part1 ) << endl;
cout << d1 << " " << ( modf ( d1, &int_part1 ) == 0.0 ) << endl;
cout << d2 << " " << modf ( d2, &int_part2 ) << endl;
cout << d1 << " " << ( modf ( d2, &int_part2 ) == 0.0 ) << endl;
cout << d2 << " " << modf ( d2, &int_part2 ) << endl;
cout << d1 << " " << ( modf ( d2, &int_part2 ) == 0.0 ) << endl;
cout << d1 << " " << fmod ( d1, 1.0 ) << endl;
cout << d1 << " " << ( fmod ( d1, 1.0 ) == 0 ) << endl;
cout << d2 << " " << fmod ( d2, 1.0 ) << endl;
cout << d2 << " " << ( fmod ( d2, 1.0 ) == 0 ) << endl;
cout.flush();
modf ( d1, 0 ); // segfault
}
Как насчет
if (abs(d1 - (round(d1))) < 0.000000001) {
printf "Integer\n"; /* Can not use "==" since we are concerned about precision */
}
Исправлено для работы с использованием округления, чтобы отразить ошибку, обнаруженную Анной
Альтернативные решения:
if ((d1 - floor(d1) < 0.000000001) || (d1 - floor(d1) > 0.9999999999)) {
/* Better store floor value in a temp variable to speed up */
printf "Integer\n"; /* Can not use "==" since we are concerned about precision */
}
Есть еще одно решение с выступлением , вычитая 0,5 и беря abs () из этого и сравнивая с 0,499999999, но я полагаю, что это не будет значительным улучшением производительности.
int iHaveNoFraction(double d){
return d == trunc(d);
}
Это не был бы C, если бы он не пересматривался за 40 лет ...
В C, ==
возвращает ] int
, но в C ++ он возвращает bool
. По крайней мере, в моем дистрибутиве Linux (Ubuntu) вам нужно либо объявить double trunc (double);
, либо вы можете скомпилировать с помощью -std = c99
, либо объявить макрос уровня, все в чтобы получить
, чтобы объявить его.
Как насчет этого?
if ((d1 - (int)d1) == 0)
// integer
попробуйте:
bool isInteger(double d, double delta)
{
double absd = abs(d);
if( absd - floor(absd) > 0.5 )
return (ceil(absd) - absd) < delta;
return (d - floor(absd)) < delta;
}
#include <math.h>
#include <limits>
int main()
{
double x, y, n;
x = SOME_VAL;
y = modf( x, &n ); // splits a floating-point value into fractional and integer parts
if ( abs(y) < std::numeric_limits<double>::epsilon() )
{
// no floating part
}
}
Ниже приведен код для тестирования d1 и d2, что делает его очень простым. Единственное, что вам нужно проверить, - это то, равно ли значение переменной тому же значению, преобразованному в тип int. Если это не так, значит, это не целое число.
#include<iostream>
using namespace std;
int main()
{
void checkType(double x);
double d1 = 555;
double d2 = 55.343;
checkType(d1);
checkType(d2);
system("Pause");
return 0;
}
void checkType(double x)
{
if(x != (int)x)
{
cout<< x << " is not an integer "<< endl;
}
else
{
cout << x << " is an integer " << endl;
}
};
Пример кода, который это делает:
if ( ABS( ((int) d1) - (d1)) )< 0.000000001)
cout <<"Integer" << endl;
else
cout <<"Flaot" << endl;
РЕДАКТИРОВАТЬ: Изменен, чтобы отразить правильный код.
Предполагая, что среда совместима с c99 и IEEE-754,
(trunc(x) == x)
является другим решением, которое (на большинстве платформ) будет иметь немного лучшую производительность, чем modf
, потому что ему нужно только создать целую часть. Оба варианта полностью приемлемы.
Обратите внимание, что trunc
дает результат с двойной точностью, поэтому вам не нужно беспокоиться о преобразованиях типов вне диапазона, как в случае с (int) x
.
Изменить: как @pavon указывает в комментарии, вам может потребоваться добавить еще одну проверку, в зависимости от того, заботитесь ли вы о бесконечности, и какой результат вы хотите получить, если x
бесконечно.