В Delphi1, используя 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, которые предназначены для преобразования значений с плавающей точкой, или валюты, в локализованную строку:
Кроме этих функций принимают строку из графических кодов, где разрешены только символы:
U+0030
. . U+0039
)).
) если число является значением с плавающей точкой (U+002E
)U+002D
)Что было бы хорошим способом1 конвертировать значение с плавающей точкой, или валюту, в строку, которая подчиняется этим правилам? например,
1234567.893332
-1234567
, учитывая, что локаль локального пользователя (т.е. моего компьютера):
-
для указания отрицательного значения (например, --
).
для указания десятичной точки (например, ,
)0123456789
для обозначения цифр (например, -
) 0123456789
. [удалены арабские цифры, которые приводят к краху SO javascript парсера])Ужасный, ужасный, хакерский, который я мог бы использовать:
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
calls:
Note
DecimalSeparator: Char
, единственный символ в мире устарел, и заменен другим десятичным разделителем 1 в моей версии Delphi
2 и в текущих версиях Delphi