В Delphi 1 использование FloatToStrF
или CurrToStrF
будет автоматически использовать символ DecimalSeparator
для представления десятичной метки. К сожалению, DecimalSeparator
объявлен в SysUtils как Char
1,2:
var
DecimalSeparator: Char;
Пока LOCALE_SDECIMAL
может быть до трех символов:
Символы, используемые для десятичного разделителя, например, "." в "3.14" или "," в "3,14". Максимальное количество символов, разрешенных для этой строки, равно четырем, включая завершающий нулевой символ.
Это приводит к тому, что Delphi не сможет правильно прочитать десятичный разделитель; назад, чтобы принять децимальный разделитель по умолчанию ".
":
DecimalSeparator := GetLocaleChar(DefaultLCID, LOCALE_SDECIMAL, '.');
На моем компьютере который является довольно символом, это приводит к неправильной локализации значений с плавающей запятой и валютой с помощью U + 002E (полная остановка) десятичная метка.
i am готовы напрямую вызвать функции Windows API, которые предназначены для преобразования значений с плавающей запятой или валюты в локализованную строку:
За исключением этих функций берется строка кодов изображений, в которой допускаются только следующие символы:
- Символы "0" - "9" (
U+0030
..U+0039
) - Одна десятичная точка (
.
), если число является значением с плавающей запятой (U+002E
) - Знак минус в позиции первого символа, если это отрицательное значение (
U+002D
)
Что было бы хорошим способом 1 преобразовать значение с плавающей запятой или валютой в строку, которая подчиняется этим правилам? например
-
1234567.893332
-
-1234567
учитывая, что локаль локального пользователя (то есть мой компьютер):
- может не использовать
-
для указания отрицательного (например,--
) - не может использовать
.
для указания десятичной точки (например,,,
) - может не использовать латинский алфавит
0123456789
для представления цифр (например, [удаленные арабские цифры, которые разбивают SO javascript parser])
Ужасный, ужасный, взломанный, который я мог бы использовать:
function FloatToLocaleIndependantString(const v: Extended): string;
var
oldDecimalSeparator: Char;
begin
oldDecimalSeparator := SysUtils.DecimalSeparator;
SysUtils.DecimalSeparator := '.'; //Windows formatting functions assume single decimal point
try
Result := FloatToStrF(Value, ffFixed,
18, //Precision: "should be 18 or less for values of type Extended"
9 //Scale 0..18. Sure...9 digits before decimal mark, 9 digits after. Why not
);
finally
SysUtils.DecimalSeparator := oldDecimalSeparator;
end;
end;
Дополнительная информация о цепочке функций, которую использует VCL:
-
FloatToStrF
иCurrToStrF
вызывает:-
FloatToText
звонки:
-
Примечание
-
DecimalSeparator: Char
, одиночный символ global устарел и заменен другим разделителем на один символ
1 в моей версии Delphi
2 и в текущих версиях Delphi