Просто реал

Clarion, Clarion 7

Модератор: Дед Пахом

Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
Алексей- Софт-Центр
Ветеран
Сообщения: 375
Зарегистрирован: 26 Август 2009, 11:41
Откуда: Moscow
Контактная информация:

Просто реал

Сообщение Алексей- Софт-Центр » 29 Март 2019, 12:14

Добрый день!
Немного поплакаться! )))
Кларион 10, Windows 7 (не играет роли)
Задача отбросить третий знак после точки. Переменная Real.
Все время делал это умножая переменную на 100, присвоением Long , ну и делением на 100.
Знаю прекрасно как хранится real в памяти, но все же......
Есть:
X real
Y Long
Z real
X=531.51
Y=X*100
Возмутило вот что:
STOP(Y&'='&X*100)
Дает результат : 53150=53151
Вероятнее всего мишень умножения - real, отсюда и результат.
Cпасает только через присвоение Real:
X=531.51
Z=X*100
Y=Z

Алексей

Yufil
Ветеран движения
Сообщения: 1090
Зарегистрирован: 16 Май 2006, 13:34
Контактная информация:

Просто реал

Сообщение Yufil » 29 Март 2019, 13:55

Я бы вывел поле через format, а потом вырезал нужный кусок. Ну и функция Round может пригодиться.
round( x-0.005, 2) - примерно так...

Аватара пользователя
finsoftrz
Ветеран
Сообщения: 1055
Зарегистрирован: 06 Ноябрь 2014, 12:48

Просто реал

Сообщение finsoftrz » 29 Март 2019, 14:10

Я на автомате в таких случаях делаю round или int, в зависимости от того, округлить или отбросить надо. И когда работаю с real, то обычно все в real.
y=round(int(x*100)/100,0.01)
x real
y real
Ну и в виде функции оформить, чтобы в проекте не отсвечивать. Что-то типа
y=getCost(x,1)
Рязань решает.

Алексей- Софт-Центр
Ветеран
Сообщения: 375
Зарегистрирован: 26 Август 2009, 11:41
Откуда: Moscow
Контактная информация:

Просто реал

Сообщение Алексей- Софт-Центр » 29 Март 2019, 15:22

Добрый день!
y=round(int(x*100)/100,0.01)
Да, такая конструкция читабельней, да и работает)

Алексей

kreator
Ветеран
Сообщения: 3153
Зарегистрирован: 28 Май 2009, 14:54
Откуда: Москва

Просто реал

Сообщение kreator » 29 Март 2019, 15:33

Алексей- Софт-Центр писал(а):
29 Март 2019, 12:14
X=531.51
Y=X*100
Возмутило вот что:
STOP(Y&'='&X*100)
Дает результат : 53150=53151
Тут срабатывает, видимо, "правило получателя". Раз нужно целое значение, значит вот так. Вопрос как обойти, если привыкли к не совсем корректным выражениям. Вот лайфхак от меня:

Код: Выделить всё

Y = round(X * 100, 1)
We are hard at work… for you. :)

kreator
Ветеран
Сообщения: 3153
Зарегистрирован: 28 Май 2009, 14:54
Откуда: Москва

Просто реал

Сообщение kreator » 29 Март 2019, 15:40

Или вот ещё:

Код: Выделить всё

Y = X / 1 * 100
We are hard at work… for you. :)

Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 3910
Зарегистрирован: 07 Июль 2005, 9:19
Откуда: г. Ростов-на-Дону

Просто реал

Сообщение Игорь Столяров » 29 Март 2019, 15:42

Подозреваю, что именно вот в таких обсуждениях и появился лет 30 назад тип данных DECIMAL. ;)
И вроде бы тема была закрыта. Но не везде и не для всех. :)
«V» значит Вендетта !

Алексей- Софт-Центр
Ветеран
Сообщения: 375
Зарегистрирован: 26 Август 2009, 11:41
Откуда: Moscow
Контактная информация:

Просто реал

Сообщение Алексей- Софт-Центр » 29 Март 2019, 15:57

Ну, не 30, а по более ))))
Decimal хорош, но он является самым медленным из всех типов.
Так что пока тема не совсем закрыта :wink:

Алексей

Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 3910
Зарегистрирован: 07 Июль 2005, 9:19
Откуда: г. Ростов-на-Дону

Просто реал

Сообщение Игорь Столяров » 29 Март 2019, 16:11

Алексей- Софт-Центр писал(а):
29 Март 2019, 15:57
самым медленным из всех типов
Биткоины майните ? ;) Ничего, что я по фене ? :)
«V» значит Вендетта !

Аватара пользователя
finsoftrz
Ветеран
Сообщения: 1055
Зарегистрирован: 06 Ноябрь 2014, 12:48

Просто реал

Сообщение finsoftrz » 29 Март 2019, 16:25

Игорь Столяров писал(а):
29 Март 2019, 15:42
Подозреваю, что именно вот в таких обсуждениях и появился лет 30 назад тип данных DECIMAL. ;)
И вроде бы тема была закрыта. Но не везде и не для всех. :)
Лучше базы еще никто ничего не придумал, как говорят культуристы. :-) Кстати, Игорь, а как Вы храните количество или цену в decimal? Они могут быть с разным количеством знаков после запятой.
Рязань решает.

Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 3910
Зарегистрирован: 07 Июль 2005, 9:19
Откуда: г. Ростов-на-Дону

Просто реал

Сообщение Игорь Столяров » 29 Март 2019, 17:05

finsoftrz писал(а):
29 Март 2019, 16:25
Лучше базы еще никто ничего не придумал, как говорят культуристы.
Оно как бы да, но всё время париться с контролем округления тоже тяжко … :(
finsoftrz писал(а):
29 Март 2019, 16:25
Они могут быть с разным количеством знаков после запятой.
Берём по максимуму. Например для цены DECIMAL(13,4), для кол-ва DECIMAL(13,3), для коэффициентов DECIMAL(15,6) и т.д.
А реальная используемая точность определяется настройкой - для всего ассортимента (если мы говорим о торговых программах).
Т.е. если есть весовой товар, то кол-во будет 1.000 шт., 2.340 метра, 5.678 кг. и т.д.
Была программа, где точность кол-ва была привязана к его единице измерения - но это на любителя, не красиво в отчётах.

Сразу хочу сказать, что я не антагонист REAL. Этот тип данных используется, но по назначению - там где требуется "беспредельная"
точность вычислений. :)
«V» значит Вендетта !

Аватара пользователя
finsoftrz
Ветеран
Сообщения: 1055
Зарегистрирован: 06 Ноябрь 2014, 12:48

Просто реал

Сообщение finsoftrz » 29 Март 2019, 17:25

Ну, я так и думал. Тогда Вам без round все равно не обойтись. Кроме того, есть еще проблема неявных промежуточных округлений в расчетах. Добавим сюда разницу в скорости работы и специфичность реализации формата decimal в разных субд (помните про историю с btrieve?) - получается, что целесообразность использования decimal вместо real совсем не очевидна. У real есть единственный вопрос с округлениями, которые надо делать явно. Где-то сразу, где-то в конце цепочки расчетов. Не нравится явно писать round с указанием точности, можно подтянуть функции-надстройки для округления суммы, количества и т.п. (iPrice, iSum, iQuantity). У меня все это есть, хотя по привычке на автомате чаще пишу просто round.
Рязань решает.

Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 3910
Зарегистрирован: 07 Июль 2005, 9:19
Откуда: г. Ростов-на-Дону

Просто реал

Сообщение Игорь Столяров » 29 Март 2019, 17:50

finsoftrz писал(а):
29 Март 2019, 17:25
Тогда Вам без round все равно не обойтись.
Да, конечно - Round() юзается … но такого беспредела как в первом посте этой темы - с DECIMAL в принципе быть не может.
finsoftrz писал(а):
29 Март 2019, 17:25
(помните про историю с btrieve?)
Нет никаких проблем. Btrieve прекрасно работает с DECIMAL, но если это поле используется в ключах и индексах
(что в общем-то экзотика), то надо использовать родной тип PDECIMAL. И всё. :)

Я придерживаюсь академической точки зрения. Тип данных DECIMAL - создан и предназначен для финансовых расчётов.
REAL - конечно более универсален и совместим в различных системах данных (говорят ещё и быстрее) - но у него своё назначение.

Я знаю одну банковскую систему, где вообще для скорости и точности расчётов используются только целочисленные операции.
С эквайрингом Сбера работали ? ;)
«V» значит Вендетта !

Аватара пользователя
finsoftrz
Ветеран
Сообщения: 1055
Зарегистрирован: 06 Ноябрь 2014, 12:48

Просто реал

Сообщение finsoftrz » 29 Март 2019, 19:13

Ну так, в клиппере, если не ошибаюсь, использовались только целочисленные вычисления. А sqlite вообще все в строках хранит. В общем, возможны разные варианты...
Рязань решает.

PavelNK
Старожил
Сообщения: 221
Зарегистрирован: 15 Март 2011, 8:02

Просто реал

Сообщение PavelNK » 29 Март 2019, 22:47

Как только наступите на REAL-ные грабли, так сразу начнете использовать DECIMAL вместо REAL.
Рассказываю, как можно легко на них наступить.
При различных вычислениях можно получить разницу миллиардные доли или даже меньше.
При попытке записать число в виде строки можете получить число, которое будет выглядеть, например как 1.65.
А число на самом деле 1.65 умноженное на 10 в степени -9.

Ответить