Определите, какую функцию вызывать на основе длины десятичной дроби - PullRequest
2 голосов
/ 17 января 2010

В C # у меня есть ситуация, когда у меня есть два возможных числа в текстовом поле управления.

Числа могут быть либо:

а) .хххх

или

б) .хх

Как написать условие, которое говорит: «Если в текстовом поле 4 знака после запятой, то вызовите эту функцию, в противном случае, если в текстовом поле 2 знака после запятой, вызовите эту функцию».

Кажется, легко, но я не знаю, как оценить десятичные знаки.

Большое спасибо!

Ответы [ 5 ]

3 голосов
/ 17 января 2010
if(txtNumber.Text.Split(new[]{'.'})[1].Length == 2)
{
    //case b
}
else
{
    //case a
}

вы можете захотеть взять десятичный разделитель из текущей культуры системы вместо жесткого кодирования точки.

2 голосов
/ 17 января 2010

Вы можете использовать Regex

new Regex(@"\.\d{2}$").IsMatch(input.Value)
2 голосов
/ 17 января 2010

Вы можете воспользоваться очень неясной функцией типа Decimal. Его внутреннее представление представляет собой 96-битное число с показателем степени. Показатель степени равен количеству цифр в дроби, даже если дробные цифры равны нулю. Таким образом:

public static int GetFractionalDigits(string txt) {
  decimal value = decimal.Parse(txt);
  return (decimal.GetBits(value)[3] >> 16) & 0x7fff;
}

Используйте decimal.TryParse (), если вам нужно проверить ввод пользователя.

1 голос
/ 08 декабря 2011

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

static class MathCustom
{
    static public byte NumberOfDecimals(decimal value)
    {
        sbyte places = -1;
        decimal testValue;

        do
        {
            places++;
            testValue = Math.Round(value, places);
        } while (testValue != value);

        return (byte)places;
    }

    static public byte NumberOfDecimals(float value)
    {
        sbyte places = -1;
        float testValue;

        do
        {
            places++;
            testValue = (float)Math.Round((decimal)value, places);
        } while (testValue != value);

        return (byte)places;
    }

    /// <summary>
    /// This version of NumberOfDecimals allows you to provide a Maximum
    /// for allowable decimals. This method will allow for the correction
    /// of floating point errors when it is less than 10 or passed in as null.
    /// </summary>
    /// <param name="value">Value to check the number of held decimal places</param>
    /// <param name="knownMaximum"></param>
    /// <returns>The number of decimal places in Value.</returns>
    static public byte NumberOfDecimals(decimal value, byte? knownMaximum)
    {
        byte maximum;
        decimal localValue;
        sbyte places = -1;
        decimal testValue;

        if (knownMaximum == null)
        {
            maximum = 9;
        }
        else
        {
            maximum = (byte)knownMaximum;
        }

        localValue = Math.Round(value, maximum);

        do
        {
            places++;
            testValue = Math.Round(localValue, places);
        } while (testValue != localValue);

        return (byte)places;
    }

}
1 голос
/ 17 января 2010

Условие оценивает true в двух, но не четырех десятичных разрядах:

Math.Round( 100*x ) == 100*x

РЕДАКТИРОВАТЬ: вышеуказанное условие работает только для десятичного типа. Ну, следующие работы для действительных чисел всех типов:

( Math.Ceiling( 100 * x ) - 100 * x ) < 10e-8 )

РЕДАКТИРОВАТЬ: Что ж, если вас интересуют строки, используйте следующее (строка расширения содержит последнюю точку и последующие цифры / цифры):

System.IO.Path.GetExtension( input ).Length
...