![]() |
#14 |
Участник
|
Цитата:
Сообщение от valentino
![]() Может я недостаточно четко сформулировал вначале, суть сводится к следующему:
при стандартных региональных настройках в панели управления, преобразование из числа в строку а затем из строки в число работает некорректно: X++: s = num2str(123456.78, 10, 2, -1, -1); // s ="123 456.78" (с пробелом, код которого = 32) num = str2num(s); // num = 123, в то время как ожидалось 123456.78 !!! Вы описали бессмысленную, с моей точки зрения, задачу. Преобразовать число в строку, а затем из полученной строки снова сделать число. Зачем? Почему нельзя было взять исходной число без этих преобразований? Есть правила перевода числа в строку. Есть правила перевода строки в число. Эти правила вовсе не обязаны быть взаимно-однозначны. Могут, но не обязательно. Попробуйте сформулировать, хотя бы для самого себя, какова конечная цель? Вы хотите, чтобы алгоритмы преобразования число-строка и строка-число были взаимно-однозначны? По каким правилам? Почему правила должны быть именно такими? Или вам надо преобразовать вполне конкретную символьную строку (сформированную по определенным правилам) в число? Если стоит всего-лишь вторая задача, то посмотрите мой пример преобразования символьной строки в число. Алгоритм достаточно сложен. А ведь я это писал под вполне конкретную задачу. Хотя и постарался сделать код, по-возможности, достаточно универсальным. Код: // Конвертация символьной строки в число // Данный метод не анализирует возможность того, что один из разделителей может являться частью другого // Например, разделитель целой и дробной части - это две точки подряд, а разделитель троек цифр - одна точка // Последствия использования подобных разделителей в данном методе могут быть парадоксальными (не ожидАемыми) // Примеры вызова /* print global::rtg_str2num("123.45"); // 123.45 print global::rtg_str2num("1 234 567.89"); // 1234567.89 print global::rtg_str2num("1 234 567.89e-2"); // 12345.6789 print global::rtg_str2num("1 234 567,89",","); // 1234567.89 print global::rtg_str2num("123,5","","",","); // 123e5 = 12 300 000 print global::rtg_str2num("123.4,1","","",","); // 123.4e1 = 1234 print global::rtg_str2num("123e4.1","e","","."); // 123.4e1 = 1234 print global::rtg_str2num("123e4","e","","."); // 123.4 pause; return; */ #define.point(".") #define.separator(" ") #define.base("e") public static real rtg_str2num( str _string, // собственно строка, которую надо перевести "123 456.78" str _point = #point, // разделитель целой и дробной части str _separator = #separator, // разделитель троек цифр str _base = #base // Основание. Разделитель мантиссы и порядка числа, если оно представлено в форме "123e-2" ) { ; // Как правило, параметр не указывают, если хотят указать значение параметра, следующего за ним, // а значение пропущенного параметра предполагается считать значением по умолчанию if (! _point) { _point = #point; } if (! _separator) { _separator = #separator; } if (! _base) { _base = #base; } // Ситуация, когда разные разделители имеют одно и то же значение рассматривается как ошибка, // поскольку становится невозможно выделить нужные части строки if (_point == _separator) { throw error(strFmt("Разделитель целой и дробной части \"%1\" не может быть равен разделителю троек цифр \"%2\"",_point, _separator)); } if (_point == _base) { throw error(strFmt("Разделитель целой и дробной части \"%1\" не может быть равен разделителю мантиссы и порядка числа \"%2\"",_point, _base)); } if (_separator == _base) { throw error(strFmt("Разделитель троек цифр \"%1\" не может быть равен разделителю мантиссы и порядка числа \"%2\"",_separator, _base)); } // Удаляю ведущие и концевые пробелы // Вообще все пробелы удалять нельзя, поскольку какой-либо символ разделитель может содержать или быть пробелом // Хотя, в принципе, эту операция можно вообще не делать, поскольку функции str2num() эти пробелы не мешают _string = global::strLRTrim(_string); // Удаляю символы разделители троек цифр if (_separator) { if (strLen(_separator) == 1) { _string = strRem(_string, _separator); } else { // Здесь strRem() использовать нельзя, поскольку необходимо удалить именно // определенную последовательность символов, а не отдельные символы _string = global::strReplace(_string, _separator, ""); } } // Если необходимо сделать две последовательные замены одного набора символов на другой, // то необходимо убедтиться в том, что вторая замена не "затрет" результат первой // т.е. в результате первой замены не должны появиться символы, которые заменит вторая замена switch (true) { case ((_base != #base) && (_point != #point) && (_point == #base) && (_base == #point)) : // Здесь нужна промежуточная замена на символы, которые не равны ни _point, ни _base // Подойдет _separator, поскольку это значение уже было проверено на данное равенство // и последовательность символов _separator была удалена из строки _string = global::strReplace(_string, _base, _separator); _string = global::strReplace(_string, _point, #point); _string = global::strReplace(_string, _separator, #base); break; case ((_base != #base) && (_point != #point) && (_point == #base)) : _string = global::strReplace(_string, _point, #point); _string = global::strReplace(_string, _base, #base); break; case ((_base != #base) && (_point != #point) && (_base == #point)) : _string = global::strReplace(_string, _base, #base); _string = global::strReplace(_string, _point, #point); break; default : if (_point != #point) { _string = global::strReplace(_string, _point, #point); } if (_base != #base) { _string = global::strReplace(_string, _base, #base); } break; } return str2num(_string); } |
|
Теги |
разделитель тысячных, axapta |
|
![]() |
||||
Тема | Ответов | |||
Разделитель страницы в MS WORD | 3 | |||
Разделитель десятичных знаков в отчетах | 0 |
|