В 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