Страница 1 из 2

Просто реал

Добавлено: 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

Алексей

Просто реал

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

Просто реал

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

Просто реал

Добавлено: 29 Март 2019, 15:22
Алексей- Софт-Центр
Добрый день!
y=round(int(x*100)/100,0.01)
Да, такая конструкция читабельней, да и работает)

Алексей

Просто реал

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

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

Y = round(X * 100, 1)

Просто реал

Добавлено: 29 Март 2019, 15:40
kreator
Или вот ещё:

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

Y = X / 1 * 100

Просто реал

Добавлено: 29 Март 2019, 15:42
Игорь Столяров
Подозреваю, что именно вот в таких обсуждениях и появился лет 30 назад тип данных DECIMAL. ;)
И вроде бы тема была закрыта. Но не везде и не для всех. :)

Просто реал

Добавлено: 29 Март 2019, 15:57
Алексей- Софт-Центр
Ну, не 30, а по более ))))
Decimal хорош, но он является самым медленным из всех типов.
Так что пока тема не совсем закрыта :wink:

Алексей

Просто реал

Добавлено: 29 Март 2019, 16:11
Игорь Столяров
Алексей- Софт-Центр писал(а): 29 Март 2019, 15:57самым медленным из всех типов
Биткоины майните ? ;) Ничего, что я по фене ? :)

Просто реал

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

Просто реал

Добавлено: 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. Этот тип данных используется, но по назначению - там где требуется "беспредельная"
точность вычислений. :)

Просто реал

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

Просто реал

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

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

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

Просто реал

Добавлено: 29 Март 2019, 19:13
finsoftrz
Ну так, в клиппере, если не ошибаюсь, использовались только целочисленные вычисления. А sqlite вообще все в строках хранит. В общем, возможны разные варианты...

Просто реал

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