Анализ чисел с плавающей запятой:Существует ли универсальный алгоритм?
-
08-06-2019 - |
Вопрос
Одна из интересных частей мультикультурного программирования - это числовые форматы.
- Американцы используют 10 000,50
- Немцы используют 10.000,50
- Французский язык использует 10 000,50
Мой первый подход состоял бы в том, чтобы взять строку, разобрать ее в обратном направлении, пока я не наткнусь на разделитель, и использовать его в качестве десятичного разделителя.В этом есть очевидный недостаток:10.000 будет интерпретироваться как 10.
Другой подход:если строка содержит 2 разных нечисловых символа, используйте последний в качестве десятичного разделителя и отбросьте остальные.Если у меня есть только один, проверьте, встречается ли он более одного раза, и отбросьте его, если это произойдет.Если оно появляется только один раз, проверьте, есть ли после него 3 цифры.Если да, откажитесь от него, в противном случае используйте его в качестве десятичного разделителя.
Очевидным "лучшим решением" было бы определить культуру пользователя или его браузер, но это не сработает, если у вас есть француз, использующий американскую Windows / браузер.
Содержит ли .net Framework какой-то мифический анализатор черной магии с плавающей запятой, который лучше, чем Double.(Try)Parse()
при попытке автоматически определить числовой формат?
Решение
Я думаю, лучшее, что вы можете сделать в этом случае, - это принять их мнение, а затем показать им, что, по вашему мнению, они имели в виду.Если они не согласны, покажите им формат, который вы ожидаете, и попросите ввести его снова.
Другие советы
Я не знаю ASP.NET сторону проблемы, но .У NET довольно мощный класс: Система.Глобализация.Информация о культуре.Вы можете использовать следующий код для синтаксического анализа строки, содержащей двойное значение:
double d = double.Parse("100.20", CultureInfo.CurrentCulture);
// -- OR --
double d = double.Parse("100.20", CultureInfo.CurrentUICulture);
Если ASP.NET каким-либо образом (т.е.используя заголовки HTTP-запроса) передает CultureInfo текущего пользователя либо CultureInfo.CurrentCulture, либо CultureInfo.CurrentUICulture, они будут работать нормально.
Ты не можешь угодить всем.Если я введу десять как 10.000, а кто-то введет десять тысяч как 10.000, вы не сможете справиться с этим без некоторого знания культуры ввода.Каким-то образом определите культуру (браузер, системные настройки - каков вариант использования?АСПИД?Внутреннее приложение или открыто для всего мира?), или приведите пример ожидаемого форматирования и используйте самый щадящий анализатор, какой только сможете.Вероятно, что-то вроде:
double d = Double.Parse("5,000.00", NumberStyles.Any, CultureInfo.InvariantCulture);
Разница между 12.345 на французском и английском языках составляет 1000 раз.Если вы укажете ожидаемый диапазон, где макс. < 1000 * мин, как вы можете легко догадаться.
Возьмем, к примеру, рост человека (включая младенцев и детей младшего возраста) в мм.
При использовании диапазона 200-3000 входное значение 1,800 или 1800 может быть однозначно интерпретировано как 1 метр и 80 сантиметров, тогда как входное значение 912,300 или 912,300 может однозначно интерпретироваться как 91 сантиметр и 2,3 миллиметра.