Как определить, является ли десятичным/двойным целое число?

Как я говорю, удваивается ли десятичное число или, значение является целым числом?

Например:

decimal d = 5.0; // Would be true
decimal f = 5.5; // Would be false

или

double d = 5.0; // Would be true
double f = 5.5; // Would be false

Причина я хотел бы знать это, состоит в том так, чтобы я мог определить программно, если я хочу произвести использование значения .ToString("N0") или .ToString("N2"). Если нет никакого значения десятичной точки, то я не хочу показывать это.

210
задан hopper 15 November 2012 в 11:25
поделиться

7 ответов

Для чисел с плавающей точкой, n % 1 == 0 обычно является способом проверить, есть ли что-нибудь после десятичной точки.

public static void Main (string[] args)
{
    decimal d = 3.1M;
    Console.WriteLine((d % 1) == 0);
    d = 3.0M;
    Console.WriteLine((d % 1) == 0);
}

Вывод:

False
True

Обновление: Как упомянул @Adrian Lopez, сравнение с небольшим значением epsilon отбросит ошибки вычислений с плавающей точкой. Поскольку вопрос касается двойных значений, ниже будет более доказательство вычислений с плавающей точкой ответ:

Math.Abs(d % 1) <= (Double.Epsilon * 100)
384
ответ дан 23 November 2019 в 04:35
поделиться

Несмотря на то, что предлагаемые решения работают на простых примерах, делать это в целом - плохая идея. Число может быть не совсем целым, но когда вы пытаетесь его отформатировать, оно достаточно близко к целому, и вы получаете 1.000000 . Это может произойти, если вы выполните расчет, который теоретически должен дать ровно 1, но на практике дает число, очень близкое, но не совсем равное единице из-за ошибок округления.

Вместо этого сначала отформатируйте его, и если ваша строка заканчивается точкой с нулями, то удалите их. Есть также некоторые форматы, в которых вы можете использовать автоматическое удаление конечных нулей. Этого может быть достаточно для вашей цели.

double d = 1.0002;
Console.WriteLine(d.ToString("0.##"));
d = 1.02;
Console.WriteLine(d.ToString("0.##"));

Вывод:

1
1.02
12
ответ дан 23 November 2019 в 04:35
поделиться

Существует несколько способов сделать это. Например:

double d = 5.0;
bool isInt = d == (int)d;

Вы также можете использовать модуль.

double d = 5.0;
bool isInt = d % 1 == 0;
44
ответ дан 23 November 2019 в 04:35
поделиться

Вы можете использовать строковое форматирование для типа double. Вот пример:

double val = 58.6547;
String.Format("{0:0.##}", val);      
//Output: "58.65"

double val = 58.6;
String.Format("{0:0.##}", val);      
//Output: "58.6"

double val = 58.0;
String.Format("{0:0.##}", val);      
//Output: "58"

Дайте мне знать, если это не поможет.

2
ответ дан 23 November 2019 в 04:35
поделиться

Как насчет этого?

public static bool IsInteger(double number) {
    return number == Math.Truncate(number);
}

Тот же код для десятичного.

Марк Байерс сделал хорошее замечание, на самом деле: это может быть не то, что вы действительно хотите. Если то, что вас действительно волнует, это является ли число, округленное до ближайших двух десятичных знаков, целым числом, вы можете сделать это вместо этого:

public static bool IsNearlyInteger(double number) {
    return Math.Round(number, 2) == Math.Round(number);
}
17
ответ дан 23 November 2019 в 04:35
поделиться
bool IsInteger(double num) {
    if (ceil(num) == num && floor(num) == num)
        return true;
    else
        return false;
}

Problemo solvo.

Редактирование: Пойман Марком Рушакоффом.

10
ответ дан 23 November 2019 в 04:35
поделиться

Ответ Марка Рушакова может быть проще, но следующее также работает и может быть более эффективным, поскольку здесь нет неявной операции деления:

     bool isInteger = (double)((int)f) == f ;

и

     bool isInteger = (decimal)((int)d) == d ;

Если вам нужно одно выражение для обоих типов, возможно,

     bool isInteger = (double)((int)val) == (double)val ;
3
ответ дан 23 November 2019 в 04:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: