Анализ чисел с плавающей запятой: существует ли алгоритм Catch All?

Одна из забавных частей мультикультурного программирования - числовые форматы.

  • Американцы используют 10000.50
  • Немцы используют 10.000,50
  • Французский использовать 10 000,50

Мой первый подход заключается в том, чтобы взять строку, разобрать ее в обратном направлении, пока я не столкнусь с разделителем, и использовать его в качестве моего десятичного разделителя. В этом есть очевидный недостаток: 10.000 будет интерпретироваться как 10.

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

Очевидным "лучшим решением" будет обнаружение культуры пользователя или браузера, но это не сработает, если у вас есть француз, использующий Windows/браузер в США.

Содержит ли .net Framework какой-то мифический парсер с плавающей запятой черной магии, который лучше Double.(Try)Parse() при попытке автоматического определения формата чисел?

Ответы

Ответ 1

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

Ответ 2

Я не знаю, с какой стороны ASP.NET проблема, но у .NET есть довольно мощный класс: System.Globalization.CultureInfo. Вы можете использовать следующий код для разбора строки, содержащей двойное значение:

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, они будут работать нормально.

Ответ 3

Вы не можете угодить всем. Если я введу десять в 10 000, а кто-то войдет в десять тысяч в 10.000, вы не сможете справиться с этим без какого-либо знания культуры ввода. Обнаружить культуру как-то (браузер, системные настройки - что такое прецедент? ASP? Внутреннее приложение или открытое миру?), Или представить пример ожидаемого форматирования и использовать самый мягкий парсер, который вы можете. Возможно, что-то вроде:

double d = Double.Parse("5,000.00", NumberStyles.Any, CultureInfo.InvariantCulture);

Ответ 4

Разница между 12.345 на французском и английском языках составляет 1000. Если вы зададите ожидаемый диапазон, где max < 1000 * мин, вы можете легко догадаться.

Возьмите, например, высоту человека (включая детей и детей) в мм.

Используя диапазон 200-3000, вход 1.800 или 1800 можно однозначно интерпретировать как 1 метр и 80 сантиметров, тогда как вход 912.300 или 912.300 может однозначно интерпретироваться как 91 сантиметр и 2,3 миллиметра.