Определите десятичную точность входного числа

У нас есть интересная проблема, были, мы должны определить десятичную точность пользовательского входа (текстовое поле). По существу мы должны знать количество вводимых десятичных разрядов и затем возвратить число точности, это лучше всего проиллюстрировано с примерами:

4 500 вводимых приведут к результату 1
4 500,1 вводимых приведут к результату 0.1
4 500,00 вводимых приведут к результату 0.01
4 500,450 вводимых приведут к результату 0.001

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

9
задан abatishchev 18 April 2016 в 22:01
поделиться

7 ответов

Работать со строкой достаточно просто.

Если нет "." в строке верните 1.

Иначе верните «0.», за которым следует n-1 «0», за которым следует одна «1», где n - длина строки после десятичной точки.

1
ответ дан 4 December 2019 в 06:14
поделиться

Нет, более простого решения нет, нужно проверить строку. Если преобразовать «4500» и «4500.00» в числа, они оба станут значением 4500 , поэтому вы не сможете определить, сколько в них незначных цифр. были за десятичным разделителем.

3
ответ дан 4 December 2019 в 06:14
поделиться

Поскольку ваши последние примеры показывают, что нули в конце строки являются значимыми, я бы исключил любое численное решение и перешел к строковым операциям.

8
ответ дан 4 December 2019 в 06:14
поделиться

Интересно отметить, что Decimal пытается сохранить точность, введенную пользователем. Например,

Console.WriteLine(5.0m);
Console.WriteLine(5.00m);
Console.WriteLine(Decimal.Parse("5.0"));
Console.WriteLine(Decimal.Parse("5.00"));

Имеет вывод:

5.0
5.00
5.0
5.00

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

2
ответ дан 4 December 2019 в 06:14
поделиться

Вот возможное решение с использованием строк;

static double GetPrecision(string s)
{ 
    string[] splitNumber = s.Split('.');
    if (splitNumber.Length > 1)
    {
        return 1 / Math.Pow(10, splitNumber[1].Length);
    }
    else
    {
        return 1;
    }
}

Здесь есть вопрос; Calculate System.Decimal Precision and Scale, который, похоже, может представлять интерес, если вы захотите углубиться в эту тему.

1
ответ дан 4 December 2019 в 06:14
поделиться

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

var decimalSeparator = NumberFormatInfo.CurrentInfo.CurrencyDecimalSeparator;

var position = input.IndexOf(decimalSeparator);

var precision = (position == -1) ? 0 : input.Length - position - 1;

// This may be quite unprecise.
var result = Math.Pow(0.1, precision);

Есть еще одна вещь, которую вы можете попробовать - тип Decimal хранит значение внутренней точности. Поэтому вы можете использовать Decimal.TryParse() и проверить возвращаемое значение. Возможно, алгоритм разбора сохраняет точность входных данных.

Наконец, я бы посоветовал не пытаться использовать числа с плавающей запятой. Простой разбор входных данных удалит любую информацию о нулях в конце. Поэтому вам придется добавлять искусственную ненулевую цифру, чтобы сохранить их, или делать подобные трюки. Вы можете столкнуться с проблемами точности. Наконец, найти точность на основе числа с плавающей запятой тоже не просто. Я вижу уродливую математику или цикл, умножающий на десять каждую итерацию, пока не останется ни одной дробной части. И цикл приходит с новыми проблемами точности...

UPDATE

Парсинг в десятичную дробь работает. Смотрите Decimal.GetBits() для подробностей.

var input = "123.4560";

var number = Decimal.Parse(input);

// Will be 4.
var precision = (Decimal.GetBits(number)[3] >> 16) & 0x000000FF;

Отсюда использование Math.Pow(0.1, precision) не вызывает затруднений.

16
ответ дан 4 December 2019 в 06:14
поделиться

Просто интересно, есть ли что-нибудь попроще решение этого.

Нет.

Используйте строку:

string[] res = inputstring.Split('.');
int precision = res[1].Length;
11
ответ дан 4 December 2019 в 06:14
поделиться
Другие вопросы по тегам:

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