FloatToStr — Функция Delphi

FloatToStr — Функция Delphi

уЕТЧЕТ РПДДЕТЦЙЧБЕФУС
ЛБЖЕДТПК ЙОЖПТНБФЙЛЙ Й ЧЩЮЙУМЙФЕМШОПК ФЕИОЙЛЙ зТзх
ФЕМ. +375-(0)152-445-101
E-mail : kadan@grsu.grodno.by

рТЕПВТБЪПЧБОЙЕ ЮЙУЕМ У РМБЧБАЭЕК ФПЮЛПК. жХОЛГЙС FloatToStrF

вПМШЫЕ ЧПЪНПЦОПУФЕК ДМС ХРТБЧМЕОЙС ЖПТНБФПН ЧЩЧПДБ ДБЕФ ЖХОЛГЙС:

function FloatToStrF(Value: Extended; Format:TFloatFormat;
Precision, Digits: Integer): string;

ъДЕУШ Value ? РТЕПВТБЪХЕНПЕ ЪОБЮЕОЙЕ, Format ? ПДЙО ЙЪ РТЕДПРТЕДЕМЕООЩИ ЖПТНБФПЧ. иПФС ЬФПФ РБТБНЕФТ ЙНЕЕФ ФЙР TFloatFormat, ПО ЙНЕЕФ ПЮЕОШ НОПЗП ПВЭЕЗП У ФЙРБНЙ РТЕПВТБЪПЧБОЙК Ч ЖХОЛГЙЙ Format (УУЩМЛЙ ОБ ОЙИ ЕУФШ Ч РТЕДМБЗБЕНПК ФБВМЙГЕ). рБТБНЕФТ Precision ЪБДБЕФ ПВЭЕЕ ЮЙУМП УЙНЧПМПЧ Ч ЧЩИПДОПК УФТПЛЕ Й ОЕ ДПМЦЕО РТЕЧЩЫБФШ 7 ДМС ЖБЛФЙЮЕУЛПЗП РБТБНЕФТБ ФЙРБ Single, 15 ? ДМС Double Й 18 ? ДМС Extended. Digits ? ЬФП РБТБНЕФТ, ЙОФЕТРТЕФЙТХЕНЩК Ч ЪБЧЙУЙНПУФЙ ПФ ЪОБЮЕОЙС РБТБНЕФТБ Format:

ffExponent оБХЮОЩК ЖПТНБФ, УППФЧЕФУФЧХЕФ ФЙРХ Е. Precision ЪБДБЕФ ПВЭЕЕ ЮЙУМП УЙНЧПМПЧ, Digits ? ЮЙУМП ЪОБЛПЧ Ч РПЛБЪБФЕМЕ ЬЛУРПОЕОФЩ (0-4).
ffFixed жПТНБФ У ЖЙЛУЙТПЧБООПК ФПЮЛПК; УППФЧЕФУФЧХЕФ ФЙРХ f. Precision ЪБДБЕФ ПВЭЕЕ ЮЙУМП УЙНЧПМПЧ, Digits ? ЮЙУМП ЪОБЛПЧ РПУМЕ ЪБРСФПК (0-18). еУМЙ ЪОБЮЕОЙЕ Precision НБМП ДМС РТЕДУФБЧМЕОЙС ЮЙУМБ, ЙУРПМШЪХЕФУС ОБХЮОЩК ЖПТНБФ.
ffGeneral пВПВЭЕООЩК ЖПТНБФ, УППФЧЕФУФЧХЕФ ФЙРХ g (УН. ПРЙУБОЙЕ ЖХОЛГЙЙ Format).
ffNumber пФМЙЮБЕФУС ПФ fTPixed ОБМЙЮЙЕН УЙНЧПМПЧ-ТБЪДЕМЙФЕМЕК ФЩУСЮ (УН. ФЙР РТЕПВТБЪПЧБОЙС Р).
ffCurrency уППФЧЕФУФЧХЕФ ФЙРХ РТЕПВТБЪПЧБОЙС Ф. рБТБНЕФТ Digits ЪБДБЕФ ЮЙУМП УЙНЧПМПЧ РПУМЕ ДЕУСФЙЮОПК ФПЮЛЙ Ч ЧЩИПДОПК УФТПЛЕ (0-18).

ч УМХЮБЕ, ЛПЗДБ Ч ЖХОЛГЙА РЕТЕДБОЩ ЪОБЮЕОЙС Value, УППФЧЕФУФЧХАЭЙЕ ПУПВЩН УМХЮБСН УПРТПГЕУУПТБ («ОЕ-ЮЙУМП», РМАУ Й НЙОХУ ВЕУЛПОЕЮОПУФШ), ПОБ ЧПЪЧТБЭБЕФ УППФЧЕФУФЧЕООП УФТПЛЙ ‘NAN’, ‘INF’ Й ‘-INF’.

FloatToStr — Функция Delphi

The Value type may be any of the floating point types.

The Format parameter is defined by the TFloatFormat (SysUtils) type :

ffCurrency eg : ?2,345.60
ffExponent eg : 2.3456E+04
ffFixed eg : 2345.60
ffGeneral eg : 2345.6
ffNumber eg : 2,345.6

The other parameters are dependent on this format. See TFloatFormat for full details.

Version 2 of this function is for use within threads. You furnish the FormatSettings record before invoking the call. It takes a local copy of global formatting variables that make the routine thread safe. Notes You can change the currency string from the default (such as ‘$’ in the USA, ‘?’ in the UK) using the CurrencyString variable.

You can change the position of the currency string using the CurrencyFormat variable.

You can change the decimal point value by setting the DecimalSeparator character.

You can change the thousands separator value by setting the ThousandSeparator character.

If the full number of digits before the decimal point (the mantissa) cannot be displayed, then the display reverts to the exponent (scientific) format. Related commands

CurrencyDecimals Defines decimal digit count in the Format function
CurrencyFormat Defines currency string placement in curr display functions
CurrencyString The currency string used in currency display functions
DecimalSeparator The character used to display the decimal point
FloatToStr Convert a floating point value to a string
NegCurrFormat Defines negative amount formatting in currency displays
TFloatFormat Formats for use in floating point number display functions
ThousandSeparator The character used to display the thousands separator
Author links
Buy Website Traffic at
Buywebsitetrafficexperts.com

Buy Proxies at
Buyproxies.io Download this web site as a Windows program.

Example code : Display numbers as financial values
var
amount1 : Extended;
begin
amount1 := 1234.567;

// Display in a Currency format
CurrencyString := ‘? ‘;
ShowMessage(‘Using 8,4 = ‘+ floattostrf (amount1, ffCurrency, 8, 4));
ShowMessage(‘Using 4,4 = ‘+ floattostrf (amount1, ffCurrency, 4, 4));
ShowMessage(‘Using 4,2 = ‘+ floattostrf (amount1, ffCurrency, 4, 2));
ShowMessage(‘Using 2,4 = ‘+ floattostrf (amount1, ffCurrency, 2, 4));
end;

Show full unit code
Using 8,4 = ? 1,234.5670
Using 4,4 = ? 1,235.0000
Using 4,2 = ? 1,235.00
Using 2,4 = 1.2E0003
Example code : Display numbers with Scientific formatting
var
amount1 : Extended;
begin
amount1 := 1234.567;

// Display in a Scientific format
ShowMessage(‘Using 8,4 = ‘+ floattostrf (amount1, ffExponent, 8, 4));
ShowMessage(‘Using 4,4 = ‘+ floattostrf (amount1, ffExponent, 4, 4));
ShowMessage(‘Using 4,2 = ‘+ floattostrf (amount1, ffExponent, 4, 2));
ShowMessage(‘Using 2,4 = ‘+ floattostrf (amount1, ffExponent, 2, 4));
end;

Show full unit code
Using 8,4 = 1.2345670E+0003
Using 4,4 = 1.235E+0003
Using 4,2 = 1.235E+03
Using 2,4 = 1.2E+0003
Example code : General display of numbers
var
amount1 : Extended;
begin
amount1 := 1234.567;

// Display in Fixed format
ShowMessage(‘Fixed formatting :’);
ShowMessage(»);
ShowMessage(‘Using 8,4 = ‘+ floattostrf (amount1, ffFixed, 8, 4));
ShowMessage(‘Using 4,4 = ‘+ floattostrf (amount1, ffFixed, 4, 4));
ShowMessage(‘Using 4,2 = ‘+ floattostrf (amount1, ffFixed, 4, 2));
ShowMessage(‘Using 2,4 = ‘+ floattostrf (amount1, ffFixed, 2, 4));

// Display in General format
ShowMessage(»);
ShowMessage(‘General formatting :’);
ShowMessage(»);
ShowMessage(‘Using 8,4 = ‘+ floattostrf (amount1, ffGeneral, 8, 4));
ShowMessage(‘Using 4,4 = ‘+ floattostrf (amount1, ffgeneral, 4, 4));
ShowMessage(‘Using 4,2 = ‘+ floattostrf (amount1, ffGeneral, 4, 2));
ShowMessage(‘Using 2,4 = ‘+ floattostrf (amount1, ffGeneral, 2, 4));

// Display in Number format
ShowMessage(»);
ShowMessage(‘Number formatting :’);
ShowMessage(»);
ShowMessage(‘Using 8,4 = ‘+ floattostrf (amount1, ffNumber, 8, 4));
ShowMessage(‘Using 4,4 = ‘+ floattostrf (amount1, ffNumber, 4, 4));
ShowMessage(‘Using 4,2 = ‘+ floattostrf (amount1, ffNumber, 4, 2));
ShowMessage(‘Using 2,4 = ‘+ floattostrf (amount1, ffNumber, 2, 4));
end;

Show full unit code
Fixed formatting :

Using 8,4 = 1234.5670
Using 4,4 = 1235.0000
Using 4,2 = 1235.00
Using 2,4 = 1.2E0003

Using 8,4 = 1234.567
Using 4,4 = 1235
Using 4,2 = 1235
Using 2,4 = 1.2E0003

Using 8,4 = 1,234.5670
Using 4,4 = 1,235.0000
Using 4,2 = 1,235.00
Using 2,4 = 1.2E0003

Delphi FloatToStr — Почему дисплей отличается?

Использование DEFAULT функции FloatToStr

сбросив один ноль после десятичной точки

Может кто-то пожалуйста, объясните, почему значение во втором случае не выводится

Преобразования используют общий формат число с 15 значащими цифрами.

Для того, чтобы интерпретировать это заявление вам нужно также обратиться к теме , описывающее Format функцию, и , в частности текст относительно формата общего числа (курсив мой):

Значение преобразуется в кратчайшую десятичную строку , используя фиксированный или научный формат. Количество значащих цифр в полученной строке задается спецификатором точности в строке формата; по умолчанию точность 15 предполагается , если не Спецификатор точности нет. Завершающие нули удаляются из результирующей строки, и десятичная точка появляется только при необходимости. Результирующая строка использует формат с фиксированной точкой , если число цифр слева от десятичной запятой в значении меньше или равна заданной точностью, и , если значение больше или равно 0,00001 . В противном случае результирующая строка использует научный формат.

К сожалению, документация на самом деле ошибка там. Вместо 0.00001 него следует читать 0.0001 . То, что это иллюстрируется в этой программе:

Для ваших примеров, 0.0000442615029219009 меньше 0.0001 и поэтому отформатирован с использованием научной нотации. Но 0.000442615029219009 больше 0.0001 и поэтому получает отформатирован с использованием фиксированных обозначений.

Если вы хотите , чтобы ваш выход всегда использовать научные обозначения затем использовать Format с e форматной строкой .

FloatToStr — Функция Delphi

У меня — результат вычисления выражения, введенного пользователем.
Скажем так, что-то наподобие результата вычисления произвольного скрипта. Просчитывать, сколько знаков должен содержать результат — это ой как не просто.

>STAKANOV
Сори, чего-то протормозил проверить. Код:
FloatToStr(double(-58.399999999999999))
приводит к тому же результату

А может попробовать скопировать целиком дельфовую функцию из исходников? Там вся функция на ассемблере. Только вот не знаю двух вещей:
1. Что за <$IFDEF PIC>? (что такое <$IFDEF>я знаю).
2. Будет ли такой код потом работать под Линуксом (вызовов прерываний в нем нет)?

1. В Дельфи символ PIC определен при компиляции позиционно-независимого кода. Это необходимо для Linux, где не поддерживается таблица релокации. В винде можно и без него, но с ним не повредит — просто объем кода будет чуть-чуть побольше.
2. Заставить код работать под Linux теоретически можно (он ведь в исходном варианте там работает), но сколько на это придется угробить сил — сказать сложно.

А вообще, я бы еще поэкспериментировал с ф-цией FormatFloat . Она дает несколько иные результаты, нежели FloatToStr. Также наблюдается определенная разница между Format(‘%f’, [value]) и Format(‘%g’, [value]) .

Delphi FloatToStr — Why is the display different?

Using the DEFAULT FloatToStr function

dropping one zero after the decimal place

Can someone please explain why the value in the second case is not output to

3 Answers 3

The conversion uses general number format with 15 significant digits.

To interpret that statement you need also to refer to the topic describing the Format function, and specifically the text concerning the general number format (emphasis mine):

The value is converted to the shortest possible decimal string using fixed or scientific format. The number of significant digits in the resulting string is given by the precision specifier in the format string; a default precision of 15 is assumed if no precision specifier is present. Trailing zeros are removed from the resulting string, and a decimal point appears only if necessary. The resulting string uses the fixed-point format if the number of digits to the left of the decimal point in the value is less than or equal to the specified precision, and if the value is greater than or equal to 0.00001. Otherwise the resulting string uses scientific format.

Unfortunately the documentation is in fact in error there. Instead of 0.00001 it should read 0.0001 . That this is illustrated by this program:

For your examples, 0.0000442615029219009 is less than 0.0001 and so is formatted using scientific notation. But 0.000442615029219009 is greater than 0.0001 and so gets formatted using fixed notation.

If you want your output always to use scientific notation then use Format with the e format string.

FloatToStr — Функция Delphi

а лишь проверяет такую возможность ? Что-то не найду.

А что мешает сделать try . except и в зависимости от этого принять решение.

Т.е. так :

boo:=true;
try strtofloat(«123s»);
except boo:=false;end;
if boo=false then messagedlg(«А строка-то не float»,mterror,[mbok],0);

Хотя,возможно,есть что-то и попроще.

GanibalLector © (05.11.04 1:49) [2]
boo=false

Константы True и False для присвоения но не для сравнения !

В Дельфи сравнивать сравнительно безопасно, но не привыкай так писать !

GanibalLector © (05.11.04 1:49) [2]
Хотя,возможно,есть что-то и попроще.

есть.
boo := TextToFloat(PChar(S), Result, fvExtended);
if not boo then
showmessage(«А строка-то не float»);

2 GuAV ©
Что сказать. Вы как всегда на высоте!

Кстати ещё есть одна. TryStrToFloat


> boo := TextToFloat(PChar(S), Result, fvExtended);

А если Result ненужен ? Зачем лишние переменные вводить ?

На самом деле есть много случаев где довольно сложно проверить возможность того или иного действия. Проще сделать а потом смотреть получилось ли.

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

Стандарной функции нет.

[6]
пиши свою тогда
если бы в TryStrToFloat была проверка второго параметра на nil то можно было так сделать
if TryStrToFloat(PChar(S), PExtended(nil)^)
но такой код не будет вызывать AV лишь при «нефлотной» строки

default © (05.11.04 2:15) [9]
TryStrToFloat(PChar(S), PExtended(nil)^)

Интересная техника. Такое может работать в случае необязательного параметра импортированной внешняей функции. Например, последний параметр в CreateThread, необязательный в 2k и выше.

Однако вряд ли найдётся функция Дельфи, делающая проверку var-параметра на nil (тем более вряд ли это будет документировано), и писать свои такие функции также не советую.

> Хотя,возможно,есть что-то и попроще.

> А если Result ненужен ? Зачем лишние переменные вводить ?

var W : Integer;
AText : String;
AValue : Real;

Val( AText, AValue, W);
if W<>0 then
ShowMessage(«симовол «»+AText[W]+»» портит всю кухню»);

я вам там письмецо отправил по поводу преобразований ;>
взглянете?

> если бы в TryStrToFloat была проверка второго параметра на nil то можно было так сделать
if TryStrToFloat(PChar(S), PExtended(nil)^)

Чушь полная.
Если бы вторым параметром был бы указатель, но вторым параметром является тип Extended, поэтому AV должен возникнуть еще до вызова функции. Если каким-то чудом вы избегаете AV, то это именно чудом.

Defunct © (05.11.04 2:58) [12]
. Если каким-то чудом вы избегаете AV, то это именно чудом.

В пятерке нет этой функции — но рискну предположить, там используется VAR параметр, что эквивалентно указателю..

скажем так — ссылка не эквивалентна указателю, но реализуется именно с помощью указателя..


> jack128 © (05.11.04 03:17) [14]
> скажем так — ссылка не эквивалентна указателю

А в каких случаях отличается ?

в тех, что ссылка не может иметь неопределённого значения. В отличии от указателя, для которого есть специальный «признак неопределенного указателя» — nil. то есть указатель не указывает не на что.
ссылка — это синоним какой то существующей переменной. синонимом «ничего» ссылка быть не может.

> А в каких случаях отличается ?

Вот пример, поясняющий в каких случаях отличается:

// value — ссылка
procedure Set55(var Value:Integer);
begin
Value := 55;
end;

// value — указатель
procedure Set55_2(Value: PInteger);
begin
Value^ := 55;
end;

По ассемблерному коду эти процедуры будут идентичны, но как видите явное использование указателя предполагает применение доп. символа ^.

jack128 © (05.11.04 04:09) [16]


> jack128 © (05.11.04 04:09) [16]
> в тех, что ссылка не может иметь неопределённого значения

Даже если это отрицательное число ? :)


> Кто—то © (05.11.04 07:30) [19]
>
> > jack128 © (05.11.04 04:09) [16]
> > в тех, что ссылка не может иметь неопределённого значения
>
> Даже если это отрицательное число ? :)

LMD!

Кто—то © (05.11.04 7:30) [19]
поэтому AV должен возникнуть еще до вызова функции

Нет. Причём никакого «чуда».

jack128 © (05.11.04 4:09) [16]
Функции WinAPI часто объявляют с var параметрами. Хотя иногда есть возможность передать NULL.

В принципе Delphi функция c var параметром тоже может принимать nil. Я немного изменил пример от Defunct ©.

// value — ссылка
procedure Set55(var Value:Integer);
begin
if @Value = nil then
ShowMessage(«nil»)
else
Value := 55;
end;

// value — указатель
procedure Set55_2(Value: PInteger);
begin
if Value = nil then
ShowMessage(«nil»)
else
Value^ := 55;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Set55(PINteger(nil)^);
Set55_2(nil);
end;

Я не призываю так писать, однако при передаче nil как параметра AV гарантированно не будет.

GuAV © (05.11.04 11:04) [21]
AV гарантированно не будет.

. В вызывающей подпрограмме, если и будет, то в вызываемой.

[12]
необоснованная категоричность
никакой это не бред
увидел как-то этот трюк в исходниках Inno Pascal-я
там он использовался в WriteProcessMemory
поскольку параметр LPDWORD lpNumberOfBytesWritten
был не нужен, переменную заводить влом и документация позволяет
«Points to the actual number of bytes transferred into the specified process. This parameter is optional. If lpNumberOfBytesWritten is NULL, the parameter is ignored. «

GuAV © (05.11.04 11:04) [21]
В принципе Delphi функция c var параметром тоже может принимать nil.

Ну это лишь особенность реализации ссылок в дельфи.

default © (05.11.04 12:26) [23]
> необоснованная категоричность

почему это необоснованная?

PExtended(nil)^) = nil^ = значение из ячейки с адресом 00000000 = AV = Чушь полнейшая и т.д. все, что написано в [12].

насчет того что вы дальше написали.
так и передавайте NULL или Nil или 0.
зачем извращаться (nil^)?

Defunct © (05.11.04 20:00) [25]

PExtended(nil)^) = nil^ = значение из ячейки с адресом 00000000 = AV = Чушь полнейшая

В общем случае да.

Однако при передаче как var параметр на переменные делаются ссылки, а если в параметре разрешение указателя, то указатель будет передан как есть.
Нет смысл рарешать ссылку, если с ней никакие действия не совершаются перед передачей в функцию.

В коде вызова функций написанных на Delphi разумеется не следует так писать.

Однако если имеется внешяя функция описанная с var параметром, а в справке объявлена с соотвествующим параметром-указателем (в С var параметров нет) и документировано, что она может принимать nil то эта техника ИМХО вполне приемлема.

Вы можете сказать что это стрёмный трюк, специфичный для данной реализации. Однако не менее стрёмный чем например asm-код.

А почему для ХР дистрибутив меньше и при этом у меня в 9х вроде запустилось ?

Defunct © (05.11.04 20:00) [25]
так в том-то и дело что nil компилятор не даст передать, так как подразумевается(если это var-параметр) его изменение изнутри вызываемого кода, а «трюк» этот чтобы компилятор «съел» nil вот и всё

Функции Delphi

Стандартные функции Delphi:

Для проведения всевозможных математических вычислений и многочисленных преобразований язык программирования Delphi содержит библиотеки стандартных процедур и функций. Давайте подробнее рассмотрим стандартные функции Delphi.

Между значением и именем функции существует зависимость. Поэтому всякая функция может быть представлена как операнд некоторого выражения (к примеру, в инструкции присваивания). Для возведения числа в n-ую степень достаточно записать

откуда ln — функция, вычисляющая натуральный логарифм числа exp(x), exp — функция, вычисляющая экспоненту в степени x, x — число, n-ую степень которого надо найти, а n — степень числа x. Каждая функция обладает следующими характеристиками: тип значений, тип параметров.

Должно существовать соответствие между типом переменной (ей присваивается определенное значение функции) и типом функции. И в то же время необходимо соответствие между типом фактического параметра данной функции (фактический параметр — это параметр, который указывается при обращении к функции) и типом формального параметра. В противном случае компилятором выводится сообщение об ошибке.

Математические функции Delphi:

Библиотеки языка Delphi включаются в себя и множество математических функций:

Величину угла при использовании тригонометрических функций необходимо выражать в радианах. Чтобы преобразовать угол из градусов в радианы, используйте следующую формулу:

где a выражает угол в градусах; 3.1415926 означает число pi. На месте константы 3.1415926 с дробной частью для достижения большей точности чаще всего пользуются стандартной именованной константой pi. Тогда выражения для угла в пересчете в радианы будет выглядеть следующим образом:

Функции преобразования Delphi:

Наиболее частое использование функций преобразования связано с инструкциями, которые обеспечивают ввод/вывод какой-либо информации. Например, для вывода значения переменной c типом real в поле вывода диалогового окна (компонент Label), нужно провести преобразование числа в строку символов, которая собственно изображает данное число. Это можно достичь, применяя функцию FloatToStr, которая заменяет значение выражения (оно указано как параметр функции) его строковым представлением.

Пример.

В приведенном примере значение переменной m будете выведено в поле Label. В таблице ниже Вам будут представлены основные функции преобразования Delphi:

Применение функций Delphi:

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

Примеры.

Структура функции Delphi

Как организована инструкция функции в языке Delphi? В любом языке программирования на первом этапе описания функции указывается ее заголовок. Далее за заголовком программист описывает раздел объявления констант const (если таковы имеются), затем занимается описанием раздела объявления типов type, далее следует раздел объявления переменных var и, наконец, раздел инструкций.

В приведенном примере в заголовке функции вначале указывается зарезервированное слово function, а следом идет имя функции. Далее в скобках программист перечисляет список параметров, и вслед за ним, используя символ «:», указывает тип значения функции. В конце каждого заголовка стоит символ «;». После заголовка следуют раздел констант, раздел типов, раздел переменных. Внутри раздела инструкций кроме констант и переменных, описанных соответственно в разделах const и var, может находится переменная result.

Когда инструкции функции завершат свое выполнение, значению переменной result присваивается значение функции. Таким образом, среди всех инструкций функций необходимое присутствие инструкции, которая бы присваивала переменной result окончательное значение функции. Обычно подобная инструкция есть последняя исполняемая инструкция функции. Представим пример функции FuntToKg, преобразующей фунты в килограммы.

Delphi FloatToStr — Почему дисплей отличается?

Использование функции DEFAULT FloatToStr

сбросив один ноль после запятой

Может кто-нибудь объяснить, почему значение во втором случае не выводится в

3 ответа

Преобразование использует общий числовой формат с 15 значащими цифрами.

Чтобы интерпретировать это утверждение, вам также необходимо обратиться к теме, описывающей функцию Format , и, в частности, к тексту, касающемуся общего формата чисел (выделено мной):

Значение преобразуется в кратчайшую возможную десятичную строку, используя фиксированный или научный формат. Количество значащих цифр в результирующей строке определяется спецификатором точности в строке формата; точность по умолчанию 15 предполагается, если нет спецификатора точности. Конечные нули удаляются из результирующей строки, а десятичная точка появляется только в случае необходимости. Результирующая строка использует формат с фиксированной запятой, если число цифр слева от десятичной запятой в значении меньше или равно заданной точности, и если значение больше или равно 0,00001 . В противном случае полученная строка использует научный формат.

К сожалению, документация там на самом деле ошибочна. Вместо 0.00001 следует читать 0.0001 . Что это иллюстрируется этой программой:

Например, 0.0000442615029219009 меньше 0.0001 и поэтому отформатировано с использованием научной записи. Но 0.000442615029219009 больше, чем 0.0001 и поэтому форматируется с использованием фиксированной записи.

Если вы хотите, чтобы ваш вывод всегда использовал научную нотацию, тогда используйте Format со строкой формата e .

В какой-то момент функция FloatToStr переключается в экспоненциальный формат, чтобы ограничить количество символов в выводе. В противном случае для отображения Double может потребоваться до 300 десятичных цифр, что нецелесообразно для интерпретации.

Вы можете использовать функцию Format для указания строгих правил.

Поскольку число значащих цифр в вашей мантиссе в первом примере превышает количество отображаемых цифр, см.

Если вы хотите больше контролировать форматирование, используйте вместо этого функцию FloatToStrF.

РЕДАКТИРОВАТЬ : объяснение с количеством цифр не является правильным, см. Ответ Дэвида Хеффермана для правильного объяснения.

Можно ли использовать DecimalSeparator, чтобы заставить функции Floattostr/Strtofloat использовать десятичную точку

В настоящее время я устанавливаю DecimalSeparator в ‘.’ в каждой процедуре, которая использует эти функции.

Было бы намного проще установить это глобально в начале программы, но я обнаружил, что Delphi периодически устанавливает это в текущую локаль.

Мне нужно убедиться, что десятичная точка используется для всех преобразований независимо от того, в какой стране используется программа, поскольку это стандарт для этого типа программы и всех структур файлов и протоколов связи, числовые отображения в формах/редактирование и т. д., должны быть отформатированы таким образом.

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

Есть ли простой «правильный» способ сделать это?

Создан 21 мар. 12 2012-03-21 22:57:23 Andy k

Какая версия delphi? – David Heffernan 21 мар. 12 2012-03-21 23:08:08

2007, На самом деле приложения были запущены в D5, и в этой версии я обнаружил, что сменился DecimalSeperator. Не уверен, что 2007 год имеет такое поведение, поскольку код уже был изменен при портировании. – Andy k 21 мар. 12 2012-03-21 23:28:55

Следуйте рекомендациям NGLN с помощью ‘FormatSettings’, это единственный способ обеспечить правильную функциональность. – LU RD 21 мар. 12 2012-03-21 23:35:15

См. Также [Thread-Safeness of FloatToStr/DateToStr] (http://stackoverflow.com/a/6055369/576719) для получения дополнительных сведений о том, как использовать ‘FormatSettings’. – LU RD 22 мар. 12 2012-03-22 00:08:22

Почему бы не соблюдать пользовательские предпочтения пользователя? И коротко переключитесь на «базовый» язык только для случаев обмена данными и т. Д. – OnTheFly 22 мар. 12 2012-03-22 00:29:43

@ user539484 Я был слишком много укушен, чтобы это разрешить. – Andy k 22 мар. 12 2012-03-22 13:12:13

@ user539484: Есть случаи, когда ужасно плохая идея уважать текущие настройки локали. Один такой случай — если вы пишете математическое программное обеспечение (например, собственный AlgoSim) или интерпретатор языка сценариев или даже компилятор. (Что, если Delphi начал использовать запятые в качестве десятичных разделителей в исходном коде?) – Andreas Rejbrand 22 мар. 12 2012-03-22 17:00:18

@AndreasRejbrand, вы только дали свое собственное программное обеспечение плохую рекламу. Даже математики во всем мире имеют региональные предпочтения в обозначениях. – OnTheFly 22 мар. 12 2012-03-22 19:04:20

@ user539484: Вы не знаете, о чем говорите. AlgoSim похож на Mathematica, Maple или Matlab (да, все они действуют как десятичный разделитель), то есть вроде как Delphi, где вы пишете скрипты. Если запятая была использована как десятичный разделитель, то как в мире вы могли бы рассказать разницу между десятичным разделителем и разделителем аргументов? И почему это не компилируется в Delphi? ‘myfloat: = 1,3 + 6,9;’? Я сказал Windows использовать запятые в качестве десятичных разделителей! – Andreas Rejbrand 22 мар. 12 2012-03-22 20:01:57

@AndreasRejbrand, кажется, что вы математик, и я просто низкокачественный условно-бесплатный кодер: -D Указывая, что вы провалили после того, как другие не отрицают вашу неудачу. Почему вы вообще начали ссылаться на свое собственное программное обеспечение как на авторитет? Я никогда не слышал об этом до сегодняшнего дня. – OnTheFly 22 мар. 12 2012-03-22 20:38:40

@ user539484 Ты смущаешься! – David Heffernan 18 май. 14 2014-05-18 07:03:37

5 ответов

Я/был в предположении, что глобальная переменная DecimalSeperator не будет затронута RTL. Если нет, то все эти подпрограммы имеют необязательный параметр FormatSettings , который вы можете использовать. Globaly объявляет переменную TFormatSettings и использует ее для каждого случая этих подпрограмм.

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

Создан 21 мар. 12 2012-03-21 23:07:12 NGLN

+1, я думаю, что это было введено в Delphi2006. Никогда не полагайтесь на настройку глобального «DecimalSeparator». – LU RD 21 мар. 12 2012-03-21 23:14:27

Ах да, я вижу, что могу сделать TformatSettings.create (‘en-UK’), чтобы убедиться, что все пользователи получают правильное форматирование. – Andy k 21 мар. 12 2012-03-21 23:51:27

Да, это то, что я имел в виду Энди. Вы используете свои собственные FormatSettings, а не глобальные. И по одному на поток, если есть потоки. Во-вторых, вы можете форматировать вещи через свои собственные функции формата, в некоторых случаях, например, если у вас есть определенные бинарные требования в соответствии с определенными вертикальными системами. Я также написал пользовательские форматы. – Warren P 22 мар. 12 2012-03-22 00:03:58

@warren почему один за нить? Один глобальный экземпляр должен быть достаточным. – David Heffernan 22 мар. 12 2012-03-22 04:32:23

@NGLN: Ну, это касается RTL. См. Мой ответ. – Andreas Rejbrand 22 мар. 12 2012-03-22 05:35:32

Один глобальный экземпляр отлично, если вы не изменяете значение из потока. Очевидно, что вы не изменяете глобальный экземпляр из нескольких потоков, если не хотите создавать интересные условия гонки. – Warren P 22 мар. 12 2012-03-22 13:24:34

Вы можете исправить каждую строку до и после вызова функции RTL с некоторыми ForceLocalSeparator() и ForceDotSeparator() функций.

Создан 22 мар. 12 2012-03-22 05:32:50 az01

Да, глобальная переменная DecimalSeparator может быть изменен во время выполнения RTL, что вызвало много головной боли для меня несколько лет назад, прежде чем я понял, что это.

Дело в том, что DecimalSeparator обновляется RTL при изменении десятичного разделителя Windows, например, с помощью панели управления. Это может показаться довольно небольшой проблемой. Действительно, как часто конечный пользователь изменяет десятичный разделитель системы?

Большая проблема заключается в том, что переменная DecimalSeparator обновляется (согласно системной настройке) при каждом переключении пользователя (в Windows). Это стало для меня неожиданностью. То есть, если ваш системный параметр использует запятую ( ‘,’ ) в качестве десятичного разделителя, и вы устанавливаете DecimalSeparator := ‘.’ при запуске приложения, тогда DecimalSeparator вернется к запятой, если вы переключите пользователя (и вы заметите, что когда вы переключаетесь обратно).

Вы можете сказать RTL не обновлять десятичный разделитель

Во всяком случае, есть лучшие альтернативы DecimalSeparator , как описано в других ответах и ​​комментариях.

Создан 22 мар. 12 2012-03-22 05:34:31 Andreas Rejbrand

+1, хорошо знать, о чем заботиться, никогда не слышал о свойстве «UpdateFormatSettings». – TLama 22 мар. 12 2012-03-22 07:17:25

@TLama: Это не лекарство без недостатков. Хотя он защищает ваш код от изменений пользователем в региональных настройках, это означает, что ваше приложение нужно закрыть и перезапустить, прежде чем показывать пользователю даты, время, валюты и т. Д. В том формате, который они только что выбрали. Сохранение настроек UpdateFormatSettings True означает, что ваше приложение отвечает на эти изменения, не закрывая их первым. – Marjan Venema 22 мар. 12 2012-03-22 07:51:34

@ Марьян, ты прав. Может быть, catch ‘RM_TaskbarCreated’ и’ WM_WININICHANGE’ будет, как и функция TApplication.CheckIniChange’. Если вы получаете один из них, вы можете сказать пользователю перезапустить приложение, чтобы отразить изменения, внесенные в настройки локали. – TLama 22 мар. 12 2012-03-22 07:59:58

Отличный совет по ** UpdateFormatSettings **, спасибо за это. – Andy k 22 мар. 12 2012-03-22 15:56:57

Преобразования типов

Преобразования типов

В любом языке программирования то и дело приходится преобразовывать один тип данных в другой. К примеру, нам требуется, чтобы пользователь ввел денежную сумму. Для этого нужно использовать вещественное число с учетом того, что могут быть копейки. Однако нет компонентов, которые позволят сразу ввести вещественное число , приходится пользоваться теми компонентами, которые позволяют ввести вещественное число в виде строки:

Пользователь воспринимает это так, будто вводит сразу цифры, однако мы то знаем, что это строка только символов, изображающая число. И чтобы действительно превратить ее в число, приходится использовать преобразования типов. Некоторыми функциями, которые служат этим целям, мы уже пользовались, давайте упорядочим эти знания и изучим новые функции.

IntToStr()

Наиболее часто используемая функция . Как вы уже знаете, она принимает в качестве параметра целое число , и возвращает его в виде строки. Хотелось бы отметить еще одну особенность: эта функция предназначена для любого целого числа, не обязательно Integer . Если у вас есть переменная Byte , Word , Cardinal или Int64 , все это переменные целого типа, и для любой из них годится функция IntToStr() .

StrToInt()

Эта функция напротив, принимает в качестве параметра строку, изображающую целое число , и возвращает его в виде целого числа. Все, что было сказано о типах данных в функции IntToStr() , справедливо и для этой функции. Примеры использования:

Как видите, действия этих функций очень похожи, только в последнем случае приходится применять осторожность, чтобы не превысить диапазон возможных значений. Если вы заранее не знаете, какое число введет пользователь , лучше использовать Integer или Cardinal , если число без знака. Экономия памяти иной раз может вызвать серьезные ошибки в программе.

FloatToStr()

Эта функция принимает в качестве параметра вещественное число (то есть, число с запятой), и возвращает его в виде строки. Примеры применения почти аналогичны функции IntToStr() , однако есть одна особенность – если после запятой у Вас есть только нули, то функция вернет строку в виде целого числа:

Эта функция также предназначена для всех типов вещественных чисел.

StrToFloat()

Эта функция принимает в качестве параметра строку в виде вещественного или целого числа, и возвращает это вещественное число . Пример:

FormatFloat()

Эта функция по своему предназначению похожа на функцию FloatToStr() , однако она является гораздо более мощным инструментом. Эта функция не только возвращает вещественное число в качестве строки, но еще и позволяет задать желаемый формат этой строки. В прошлых примерах мы говорили, что функция FloatToStr() вместо строки ‘125,00’ выведет ‘125’. А если нужно все-таки ‘125,00’? Такое сплошь и рядом встречается, особенно в финансовой документации. Для этих целей и создана функция FormatFloat .

Она имеет два параметра – строку формата и само число. Строка может содержать следующие форматы:

Таблица 15.1. Возможные форматы FormatFloat()
Строка, указываемая в формате Примеры чисел
1234 -1234 0,5
1234 -1234 1
0.00 1234,00 -1234,00 0,50 0,00
#.## 1234 -1234 0,5
#,0.00 1 234,00 -1 234,00 0,50 0,00

Есть и другие варианты форматов, например, для представления числа в экспонентной форме, но они, как правило, не используются.

Поясним строку форматов подробней.

В первом случае показаны варианты возвращаемых строк, если строка форматов вообще не указана.

«Решетка» (#) работает также, как «ноль», с той разницей, что если на этом месте не окажется цифры, то «решетка» ничего не выведет, а «ноль» подставит в это место ноль.

Знак запятая здесь указывают для удобного отображения разрядности числа. Например, миллион будет выглядеть как строка ‘1 000 000’. Заметим, что на само число этот формат не оказывает никакого влияния, он нужен только для того, чтобы выводить число в удобочитаемой форме в виде строки.

Илон Маск рекомендует:  Asp взаимодействие с клиентскими сценариями
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL