delphi округление до целого | Все о Windows 10

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

Округление числа до целого значения

Для округления до целого числа используется следующий набор функций:

Ceil(X) – до целого в большую сторону;

Floor(X) – до целого в меньшую сторону;

Round(X) – число до целого в ближайшую сторону;

Trunc(X) – число до целого путем отбарасывания дробной части.

В качестве параметра эти функции используют дробное значение X и возвращают целое. Примеры округления чисел:

// до ближайшего большего целого:A := Ceil(15.15); // A = 16В := Ceil(15.95); // В = 16// до ближайшего меньшего целого:A := Floor(15.15); // A = 15В := Floor(15.95); // В = 15// по математическим правилам до ближайшего целого:A := Round(15.15); // A = 15B := Round(15.95); // B = 16C := Round(15.5); // C = 16D := Round(15.4999); // D = 15// отбрасывание дробной частиA := Trunc(15.15); // A = 15В := Trunc(15.95); // В = 15

* Несмотря на схожесть результата, Floor и Trunc имеют некоторое отличие. Floor возвращает значение типа Integer, тогда как Trunc – Int64, имеющий больший диапазон значений. Ceil так же возвращает значение Integer. Round возвращает Int64.

Округление до заданной точности знаков после запятой

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

A := SimpleRoundTo(15.1219, -1); // A = 15.1B := SimpleRoundTo(15.1219, -2); // B = 15.12C := SimpleRoundTo(15.1219, -3); // C = 15.122D := SimpleRoundTo(15.1219, -4); // D = 15.1219E := SimpleRoundTo(15.1219, -5); // E = 15.1219

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

Delphi , Синтаксис , Математика

Как научить Delphi делать правильное округление дробных чисел

Чем отличается законченный программист от простого пользователя? Пользователь думает, что в килобайте 1000 байт, а Программист думает, что в километре 1024 метра.

Еще более короткий способ:

Округление дробных чисел с точностью i — количество знаков после запятой, S — дробное число в строковом виде.

Статья Как научить Delphi делать правильное округление дробных чисел раздела Синтаксис Математика может быть полезна для разработчиков на Delphi и FreePascal.

Комментарии и вопросы

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

Комментарии и вопросы

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

Вещественные числа, в отличие от целых чисел, хранят лишь приблизительное значение, и за рубежом используются в основном для хранения научных данных. Для хранения денежных величин обычно используются целочисленные типы данных. Однако integer как правило не хватает для хранения наших денег (особенно остро стоит эта проблема в турции, где зарплату получают миллионами турецких лир). Поэтому для денег приходится использовать вещественные числа (начиная с InterBase 6.0 и в последующих версиях InterBase/Firebird/Yaffil есть поддержка int64 или bigint в третьем диалекте).

InterBase имеет 2 типа данных для хранения вещественных чисел: float и double precision. Эти типы эквивалентны дельфийским single и double, соответственно. Single имеет весьма низкую точность (длина всего 4 байта), в то время как double precision – вполне достаточную (8 байт).

Для «виртуальных» типов данных NUMERIC(precision, scale) и DECIMAL (precision, scale) при объявлении поля анализируется его точность, и IB пытается «втиснуть» его в один из физических типов – в диалекте 1: smallint, integer, float, double precision – в соответствии с указанными precision и scale, в диалекте 3: smallint, integer, in64. Таблица соответствия типов для конкретных precision и scale указана в Data Definition Guide в главе 4 Specifying Datatypes, разделе Defining numeric datatypes.

В общем правило простое: если вам нужно хранить вещественное число, то объявляйте его как NUMERIC(15, 2) или как DECIMAL(15, 2) (в диалекте 3 precision может быть до 18 знаков вместо 15). В первом диалекте при выполнении вычислений обязательно будет погрешность (из-за того, что число хранится в вещественном типе), а в третьем диалекте погрешностей не будет (число хранится как целое), но могут быть проблемы переполнения (см. подробно о реализации int64).

Для проверки точности вещественных чисел в IB необязательно создавать таблицы и выполнять SQL-операторы. Вы можете поэкспериментировать с числами double в Delphi или в C++Builder. Одновременно, можно использовать любой приведенный ниже код в качестве UDF для округления вещественных чисел как банковского, так и обычного. Одним из самых популярных решений на сегодняшний день является UDF FormatFloat.

Далее приведены примеры потери точности с разными типами вещественных чисел, и способы борьбы с этим. Информация собрана из конференций fido7.ru.delphi.db, fido7.su.dbms, fido7.su.dbms.interbase, interbase@mers.com. Авторство некоторых писем, к сожалению, утеряно.

KDV (support@ibase.ru)

Результат – -43,9400000000001. Если вместо double использовать single (эквивалент FLOAT), то результат будет еще хуже: -43,9400634765625.

Subject: Round(2.5) = 2 .

Пон Сен 14 1998, Eugeny Ivanoff == Gleb V. Ufimtsev:
==============================

Я приведу переписку из эхи по бухгалтерии, уж извини.

===== начало =========
Если я купил 100 тетрадей за 12.10 и в месяце продал 5 штук, то в оборотке появляется лишняя копейка

==== =
1. Вести учет с десятыми долями копейки.
2. Разделить пpиобpетенную паpтию на 2 комплекта: 10 штук – по 13 коп, 90 штук – по 12 коп. Тогда 10 х 0,13 + 90 х 0,12 = 12,10.
=====
AB> 1. Вести учет с десятыми долями копейки.

При тех обемах учет ведется с 6 знаками от гривны, иначе налоговая не будет корректной (12 200 шт. по 0.083333 грн без ндс).
не спасает – итоговая цифра в строчке должна быть в копейках

AB> 2. Разделить пpиобpетенную паpтию на 2 комплекта: 10 штук – по 13 коп, 90 штук – по 12 коп. Тогда 10 х 0,13 + 90 х 0,12 = 12,10.

Обясни это фирме, от которой мы привезли налоговые накладные
======
SV>> Веди учет тетрадей в тыс. шт. Если мало – в десяти тысячах штук. Проблема с копейками уйдет – проверено.

VK> Вiрно. Коли я налаштовував облiк швацького виробництва, менi намагались нав’язати облiк ниток у метрах.;-)
VK> З того часу – тiльки в умовних «катушках» по 200 м. (хоч iнодi iдуть кiлометровi бобiни.

Особенно приятно выдать на руки накладную или чек на 0.006 тыс.шт.
Люди покупают партии до 1000 000 шт., и продают поштучно!
====
Ребяты, прошу прощения, что вмешиваюсь, но, я уже писал Игорю мылом, а не легче ли пользоваться (я, кстати, уже давно пользуюсь) некоей багофичей (это, по-моему, из буржуйской банковской системы) системой округления к _ближайшему_ _четному_ – фор екзампл (из примера Игоря):

И нет никаких проблем с копейками.

IC> Имеется ввиду складской учет и оборотная ведомость, и чтоб считалась автоматом.

Все считается автоматом. Единственное – но. Hадо иметь прямые руки для написания некоей функции – обеспечивающей данное округление :)))
============= Конец ========

>>>> Это правило бухгалтерского округления.
>>>> Половинки до ближайшего четного.
>>>> Так как эта фича у дельфей была заявлена давно, то, думаю, будет обнаружена в любой версии.

EI> наpод, помему это баг, я не фича, или у амеpиканцев бухгалтеpия совсем неpуская, я эти гpабли обошел используя пеpеменную
EI> var x: real; i: integer;
EI> x:=2.5; i:=round(x);
EI> в pезультате i = 3, я думаю, что это давно можно было и фак поместить, каждый месяц на них кто-нибудь наступает 🙂

Павел Зотов

Andrew Bagirov (7034.g23@g23.relcom.ru)

Спасибо, Евгений. Без тебя не досчитался бы я копейки. 🙂

С уважением, Сергей Белов.

Документ с www.borland.com/devsupport/

Since Delphi’s Round() function uses «bankers rounding» where the value is rounded to the nearest even number, how can I round a floating point number using the more traditional means, where fractional values less than .5 round down, and fractional values of .5 and greater round up?

Answer:
The following function demonstrates rounding down numbers with fractional values of less than .5, and rounding up numbers with fractional values of .5 and greater.

Example:

Paul Bonnette

I have been using x = CAST ( ((x+0.00001)*100) AS INTEGER) /100; to fight round-off error in double precision decimals.

It forces a number into an integer representing pennies then divides back down to decimal form, removing creaping millipennies. The 10,000th of a penny (or whatever you would like to use) is added so that if the decimal representation rounds up, not truncate down.

This technique is not thoroughly tested but has worked so far without problem. Tell me if anyone finds a better technique or tests this one thoroughly.

Рейтинг
( 1 оценка, среднее 5 из 5 )
Загрузка ...