Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.57/100: Рейтинг темы: голосов - 100, средняя оценка - 4.57
49 / 49 / 5
Регистрация: 11.07.2011
Сообщений: 282
1

Double.parse(): независимость от региональных настроек

20.01.2012, 00:12. Показов 18839. Ответов 15
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Мне нужно чтобы этот метод корректно отрабатывал на числах с разделителем целой и дробной части "." и "," . То есть, автоматически определял нужные региональные настройки. как это устроить?
1
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
20.01.2012, 00:12
Ответы с готовыми решениями:

Parse, как метод класса double
Имеется следующий код. string positions = "0,-0.061426,0.9388459 -0.049693,0.200773,0.692165";...

Можно ли заставить double.Parse обрабатывать числа с разными разделителями?
Привет! Есть фреймворк, который подключен к проекту в виде библиотеки. В одном из сценариев...

Проблемы с кодировкой при отправке запроса в IE и IIS 7 после смены региональных настроек
Здравствуйте! Имеется таблица с редактируемыми строками. После нажатия на сохранить, формирую...

Как отучить C# от региональных настроек?
в моей программе я хочу чтобы работало 0.000067 (разделитель точка) в независимости от того что...

15
1319 / 992 / 127
Регистрация: 08.12.2009
Сообщений: 1,299
20.01.2012, 02:27 2
тут однозначного ответа нет. вот вариант, к которому пришёл я:
- Parse(String, IFormatProvider) в который я передаю нужный NumberFormat, причём через весь метод считывания большого текстового файла данных и на поверхности ловлю исключения открытия файла - не удалось - меняю формат и т.д. пока не откроется. если все варианты (которых обычно 2) не отработали, то наверх улетает исключение, пойманное первым (как InnerException, естественно)
1
49 / 49 / 5
Регистрация: 11.07.2011
Сообщений: 282
20.01.2012, 03:43  [ТС] 3
Спасибо.
Вот к чему пришел я:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
using System;
using System.Globalization;
 
namespace test_doubleParse
{
    class Program
    {
        static void Main(string[] args)
        {
            NumberFormatInfo nfi = NumberFormatInfo.CurrentInfo;
            string CurrentDecimalSeparator = nfi.CurrencyDecimalSeparator;
            string str_value = "3,14";
            double d = double.Parse(conversion(str_value,CurrentDecimalSeparator));
            Console.WriteLine(d  +  "\t\t\tВсе в порядке!");
            Console.ReadLine();
        }
 
        /// <summary>
        /// автоматическое преобразование чисел с любым разделителем("." или ",") в текущую для системы
        /// </summary>
        /// <param name="str1">входная строка</param>
        /// <param name="str2">разделитель в текущих региональных настройках</param>
        /// <returns></returns>
        static string conversion(string str1, string str2) {
            
            if (str1.Contains(".") && (str2 != "."))
                return  str1.Replace('.', ',');
            if (str1.Contains(",") && (str2 != ","))
                return str1.Replace(',', '.');
            return str1;
        }
    }
}
Что скажете?
1
1319 / 992 / 127
Регистрация: 08.12.2009
Сообщений: 1,299
20.01.2012, 05:44 4
Цитата Сообщение от Dimblch Посмотреть сообщение
Вот к чему пришел я
это, кстати, худший из вариантов))
1
38 / 38 / 8
Регистрация: 29.05.2011
Сообщений: 65
20.01.2012, 09:07 5
И правда не самый лучший способ. Например, в американской культуре число 200,000,111=200000111 (','-разделитиль групп разрядов).
Попробуйте везде использовать инвариантную культуру.
1
49 / 49 / 5
Регистрация: 11.07.2011
Сообщений: 282
20.01.2012, 11:12  [ТС] 6
Mikant, Вы могли быть привести пример вашей реализации, того что вы имеете ввиду? пожалуйста.

p.s.
сомневаюсь, что мой - худший вариант)
1
80 / 78 / 10
Регистрация: 29.12.2011
Сообщений: 183
22.01.2012, 00:38 7
Цитата Сообщение от Dimblch Посмотреть сообщение
привести пример вашей реализации
Имеется в виду одна из встроенных перегрузок метода Double.Parse() из .NET так что метод Microsoft.
Double.Parse - метод (String, IFormatProvider)
IFormatProvider

C#
1
2
3
//Используется текущая культура. Есть разные варианты создания экземпляра CultureInfo.
CultureInfo culture = new CultureInfo(CultureInfo.CurrentUICulture.Name);
double d = Double.Parse("2,37", culture);// CultureInfo поддерживает интерфейс IFormatProvider.
1
1 / 1 / 0
Регистрация: 20.05.2011
Сообщений: 3
15.03.2012, 15:53 8
Как вариант -
C#
1
var result = double.Parse(txbUser.Text, CultureInfo.InvariantCulture);
1
624 / 495 / 43
Регистрация: 05.07.2010
Сообщений: 1,589
16.06.2012, 11:44 9
C#
1
2
3
4
5
try
{
  Coeff = double.Parse(strCoeff.Replace(",", "."), CultureInfo.InvariantCulture); 
}
catch (Exception) { Coeff = 0.1; }
1
Эксперт .NET
17689 / 12874 / 3366
Регистрация: 17.09.2011
Сообщений: 21,138
16.06.2012, 11:55 10
Цитата Сообщение от ksk Посмотреть сообщение
C#
1
Coeff = double.Parse(strCoeff.Replace(",", "."), CultureInfo.InvariantCulture);
Что делать с числом пятьдесят тысяч и пять десятых, поданное на ввод в таком виде: "50,000.5"?
Это вполне легальный ввод для инвариантной культуры, но предложенный вами код выбросит на нем FormatException.
1
624 / 495 / 43
Регистрация: 05.07.2010
Сообщений: 1,589
16.06.2012, 12:09 11
Такого мои пользователи обычно не вводят. Им не извращаться надо, а параметр задать. Не думая при этом о точках и запятых.

В случае исключения я дисаблю кнопку ОК и крашу едит контрол красным цветом.
Так что программа защищёна от попыток свалить её посредством ввода ерунды в качестве коэффициента.

Инвариантную культуру я применяю для того, чтобы парсер правильно обработал точку, а не для того, чтобы задействовать весь функционал инвариантной культуры.
1
Эксперт .NET
17689 / 12874 / 3366
Регистрация: 17.09.2011
Сообщений: 21,138
16.06.2012, 12:37 12
Цитата Сообщение от ksk Посмотреть сообщение
Такого мои пользователи обычно не вводят.
Определенный формат ввода сделан по запросу пользователей?

Цитата Сообщение от ksk Посмотреть сообщение
Им не извращаться надо, а параметр задать.
Группирование чисел по тысячным - извращение?
Сурово.

Цитата Сообщение от ksk Посмотреть сообщение
Не думая при этом о точках и запятых.
Вот человек ввел число так, как привык - с группированием. А текстбокс красным стал. И ему приходится думать о запятых.

Цитата Сообщение от ksk Посмотреть сообщение
программа защищёна от попыток свалить её посредством ввода ерунды в качестве коэффициента.
Группирование чисел по тысячным - ерунда?
Сурово.

А теперь серьезно.
Замена запятой на точку в вашем коде говорит о том, что некоторые пользователи могут ввести значение так, а некоторые - иначе. Другими словами, ваши пользователи вводят числа так, как они привыкли это делать, исходя из настроек системы или личных предпочтений. Что, в свою очередь, не исключает ситуации, где пользователь привык вводить значения именно так: 100,000.00 (особенно бухгалтеры этим грешат).
В результате логика вашего приложения помогает одним пользователям, но не другим.
Дискриминация? Или просто большинство не отчитывается перед меньшинством?
Почему бы не предположить, что пользователь будет вводить числа так, как настроена его система и, следовательно, оставить обычный парс, учитывающий текущие настройки?
Вижу несколько причин, но хотелось бы увидеть что привело именно вас к такому решению.

Дисклаймер: в моем сообщении нет наездов или попыток поучать (почему-то некоторые это в моих сообщениях видят). Всего лишь пытаюсь вести продуктивную дискуссию с коллегами о юзабилити пользовательских интерфейсов.
2
624 / 495 / 43
Регистрация: 05.07.2010
Сообщений: 1,589
16.06.2012, 15:04 13
Если конструктивно - то мои пользователи и не пытаются делить разряды знаками препинания. Ну такие у них граничные условия. Единственная их на сегодня озвученная проблема - это неоднозначность трактовки операционной системой точки на цифровой части клавиатуры в зависимости от региональных настроек и текущего языка ввода. Мой подход от этого их защитил. Вот и всё.

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

Это вовсе не значит, что теперь из-за этого другие подходы неправомерны. Просто они для разных групп пользователей.

Одним пользователям привычно отделять разряды запятыми. Другие хотят, чтобы программе было всё равно, что введено в качестве десятичного разделителя - точка или запятая, и грузить их тем, что вот это разделитель между тысячами а вот это - разделитель между целой и дробной частью было бы в высшей степени неюзеролюбиво. Потому что им не о форматах хотелось бы думать, а о предметной области.

То есть получается, что юзабилити вне контекста применения не существует. Нужно учитывать специфику работы целевого пользователя.

Я надеюсь, что буду правильно понят и никто не подумает, что я тут с кем-то спорю. Я умею не только говорить, но и слушать. Про применение бухгалтерами запятых в качестве разделителей - это новая для меня информация, за это спасибо. Думаю, что обсуждение наличие разных сторон разбора чисел будет полезно всем читающим это.
2
Эксперт .NET
17689 / 12874 / 3366
Регистрация: 17.09.2011
Сообщений: 21,138
16.06.2012, 16:19 14
Цитата Сообщение от ksk Посмотреть сообщение
мои пользователи и не пытаются делить разряды знаками препинания.
Единственная их на сегодня озвученная проблема - это неоднозначность трактовки операционной системой точки на цифровой части клавиатуры в зависимости от региональных настроек и текущего языка ввода. Мой подход от этого их защитил.
Вот это и было интересно: требования и решение.
Спасибо за пояснение.

Цитата Сообщение от ksk Посмотреть сообщение
Никто и не сомневался в том, что это вам успешно удалось.
Ок, глумёж засчитан

Цитата Сообщение от ksk Посмотреть сообщение
Это вовсе не значит, что теперь из-за этого другие подходы неправомерны. Просто они для разных групп пользователей.
С этим и с тем, что идет после - согласен на 100%. Тоже считаю, что для отдельной проблемы нужно отдельное же решение - унификация всего и вся зачастую может только усугубить проблему.

Но вот часто приходится делать приложения, используемые довольно большим количеством людей с довольно большим разбросом по национальностям и географии, где каждый хочет чтобы было удобно именно ему, а софтина должна работать одинаково для всех. Через это порой рождаются такие уродцы, что хочется код стереть, комп сжечь, а глаза выколоть - только бы эти костыли не видеть. Потому проблема многоязыковой поддержки для меня особо актуальна, вот и интересно как люди решают подобные проблемы и чем при этом руководствуются.
1
624 / 495 / 43
Регистрация: 05.07.2010
Сообщений: 1,589
16.06.2012, 17:27 15
Да, иногда эта поддержка всего в одном стремится дойти до абсурда.
Иногда, решая проблемы одних пользователей создают проблемы другим пользователям (например, с названиями счётчиков производительности, которые в русскоязычном варианте с непривычки не сразу и найдёшь, не говоря уже о порядке их следования при алфавитной сортировке).

А в других случаях делают разные билды для разных культур. Например, насколько я понимаю, для русскоязычных пользователей MS делает отдельный билд офиса.

Оказываеся, в нашей отрасли народного хозяйства тоже невозможно быть хорошим для всех заинтересованных товарищей.
1
41 / 37 / 9
Регистрация: 01.02.2014
Сообщений: 825
15.08.2019, 19:20 16
Почему я раньше не нашел эту тему... Я столько мучался с проблемой, что при вычислениях чисел 23,12 умножаются на 100 на некоторых компьютерах. Я даже не мог представить, что в конвертировании чисел может быть такая мура, только сегодня случайно гуглил и набрел на эту тему
0
15.08.2019, 19:20
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
15.08.2019, 19:20
Помогаю со студенческими работами здесь

работа с Double.Parse
Всем привет, столкнулся со странной проблемой: в цикле идет простое преобразование из &quot;string&quot; в...

Double.Parse вызывает FormatException
Ввожу с консоли Значение double Middle_Mark = double.Parse(Console.ReadLine()); Но почему-то...

Ошибка формата входной строки при Double.Parse(string s)
есть такой кусок кода: double responsetime; try ...

Double.Parse не работает: Входная строка имела неверный формат
Double.Parse(&quot;1.1&quot;); Convert.ToDouble(&quot;1.1&quot;); В обоих случаях ошибка &quot;Входная строка имела...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru