Мастера DELPHI, Delphi programming community Рейтинг@Mail.ru Титульная страница Поиск, карта сайта Написать письмо 
| Новости |
Новости сайта
Поиск |
Поиск по лучшим сайтам о Delphi
FAQ |
Огромная база часто задаваемых вопросов и, конечно же, ответы к ним ;)
Статьи |
Подборка статей на самые разные темы. Все о DELPHI
Книги |
Новинки книжного рынка
Новости VCL
Обзор свежих компонент со всего мира, по-русски!
|
| Форумы
Здесь вы можете задать свой вопрос и наверняка получите ответ
| ЧАТ |
Место для общения :)
Орешник |
Коллекция курьезных вопросов из форумов
KOL и MCK |
KOL и MCK - Компактные программы на Delphi
Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / rsdn.org

 
Чтобы не потерять эту дискуссию, сделайте закладку « предыдущая ветвь | форум | следующая ветвь »

Округление


rosl   (09.03.17 07:23

Такой вопрос возник:
имеем 3 поля (float). в них данные:

поле      значение
P1 -         0,022
P2 -         60,7
P3 -         587

провожу расчет:
ADOTable.fields[0].value*ADOTable.fields[0].value/ADOTable.fields[0].value
результат 0,0023
но мне нужно, чтоб после запятой было 14 знаков.
должно получиться 0.00227495741056
от этого значения зависит дальнейший расчет. в оконцовке (если используется 0,0023 вместо 0.00227495741056) результат не верен на 2 сотых.


rrrrr ©   (09.03.17 08:36[1]

во первых неизвестно какая размерность поля и что там на самом деле лежит
во вторых tfield.value это variant/double у которого значащих 15 цифр
в третьих при делении точность дабла никуда не девается и не округляется сама по себе
в четвертых есть format(%x,nf)


Pavia ©   (09.03.17 08:40[2]


> ADOTable.fields[0].value*ADOTable.fields[0].value/ADOTable.
> fields[0].value

Даже формулу скопировать не могут!

В Delphi нет типа float зато есть single, double, real, extended
Это числа с плавающей точкой и вычисления в них идут по правилам IEEE 754 вот и читайте про этот формат.

Как вы выводите результат в текстовый формат?

> от этого значения зависит дальнейший расчет. в оконцовке
> (если используется 0,0023 вместо 0.00227495741056) результат
> не верен на 2 сотых.

Не на 2 сотых, а на 23 миллионных.


> но мне нужно, чтоб после запятой было 14 знаков.

Какой тип данных вам нужен?
https://ru.wikipedia.org/wiki/Число_с_плавающей_запятой

Но 14 знаков это бесполезные данные. Всё равно у вас погрешность входных данных составляет 0,5*10^-5 значащих цифр. Бессмысленно увеличивать точность внутренних расчётов, так как результат не будет точнее чем входные данные.


rosl   (09.03.17 09:12[3]

наверное плохо объяснил...
тогда так:
расчет в несколько действий. из за округлений, КОНЕЧНЫЙ РЕЗУЛЬТАТ не идет на 2 сотых (а это 2 копейки, в реальности)

есть весь расчет в EXCEL, там все работает как надо.
действие первое:
0,020*60,7/587
делаю:
s: currency;
s:=ADOTable1.Fields[1].AsFloat*ADOTable1.Fields[2].AsFloat/ADOTable1.Fields[3]AsFloat;
(постом выше VALUE вместо AsFloat - эксперементировал)
выдает результат - 0,0021 (в excel 0.00206814310051107) - в принципе правильно (округлил)
но при следующем действии:
s*1*587 выдает 1,2327 , в excel этот результат 1,2140
так вот, пробую в excel 0.00206814310051107 заменить на 0,0021 выходит 1,2327
вот они 2 сотых
и так далее...
тип полей сделал float. где рыть?
так что 14 знаков - это бесполезные данные не в моём случае


rrrrr ©   (09.03.17 09:19[4]

выдает результат - 0,0021 (в excel 0.00206814310051107)

asFloat из поля - это Double
и там не 0,0021
0,0021 это строка '0,0021' которую ты видишь после floattostr

а реальная точность дабла - 15 значащих

поэтому все дальнейшие выводы и логика неверные


rosl   (09.03.17 09:36[5]

тогда не пойму.
0.00206814310051107*587 = 1,2140
0,0021                     *587 = 1,2327

как быть?


Dimka Maslov ©   (09.03.17 09:47[6]


> как быть?


В инженерных расчётах (не знаю как в бухгалерских) принято иметь три значащих цифры, округляя в большую сторону если последняя цифра 6..9, в меньшую сторону когда 0..4, а если последняя цифра 5 округлять до чётной
0.00206814310051107 > 0.00207
0.00206423238961768 > 0.00206
0.00206522029076111 > 0.00206
0.00205556467154581 > 0.00206

В отдельных случаях принято увеличивать точность до 5-6 значащих цифр.


rrrrr ©   (09.03.17 09:50[7]

>0.0021 * 587 = 1,2327

как и в экселе?
да, как и в экселе.

считает одинаково? одинаково.

и в чем твоя печаль?


Dimka Maslov ©   (09.03.17 09:52[8]


> и в чем твоя печаль?


0.0021 - это 2 (две) значащих цифры, а не четыре, как многие могут подумать.


rrrrr ©   (09.03.17 10:03[9]

ShowMessage(Format('%1.14f',[0.022 * 60.7 / 587]));


rrrrr ©   (09.03.17 10:05[10]

и снова, в чем твоя печаль?

в том что первую строчку первого ответа не читаем?


rosl   (09.03.17 10:16[11]

ShowMessage(Format('%1.14f',[0.022 * 60.7 / 587]));
спасибо за наводку.
видимо "косяк" в полях? какой тип поставить? sql
0.022 * 60.7 / 587 = 0.00227495741056
но если я подставляю переменные (поля со значениями) = 0,0023


Inovet ©   (09.03.17 16:04[12]

> [11] rosl   (09.03.17 10:16)
> какой тип поставить? sql

Деньги надо хранить в целых (с фиксированной точкой), считать в плавающей, каждый раз приводя при сохранении к целым (с фиксированной точкой). При округлении тоже может быть неожиданно, так что надо принимать специальные меры.
http://www.delphikingdom.com/asp/viewitem.asp?catalogID=374
и там же есть про функции округления для денег.


Inovet ©   (09.03.17 16:06[13]

DecimalRounding_JH1


rosl   (09.03.17 19:54[14]

Всем спасибо за ответы, разобрался

var
s: Real;


Германн ©   (10.03.17 01:50[15]


> rosl   (09.03.17 19:54) [14]
>
> Всем спасибо за ответы, разобрался
>
> var
> s: Real;
>

Хреново разобрался, если решил использовать тип Real.


rosl   (10.03.17 18:20[16]

>Хреново разобрался, если решил использовать тип Real.

срочно нужно было. а real помог
мне на данный момент нужен быстрый результат


версия для печати

Написать ответ

Ваше имя (регистрация  E-mail 







Разрешается использование тегов форматирования текста:
<b>жирный</b> <i>наклонный</i> <u>подчеркнутый</u>,
а для выделения текста программ, используйте <code> ... </code>
и не забывайте закрывать теги! </b></i></u></code> :)


Наверх

  Рейтинг@Mail.ru     Титульная страница Поиск, карта сайта Написать письмо