Что-то мне становится нехорошо

30 views
Skip to first unread message

Petr Ageev

unread,
Dec 15, 1998, 3:00:00 AM12/15/98
to
Hello All!

Имеем числовое поле PLOSH типа real или decimal(n,2), что пофигу. Требуется
получать округленные значения с одним десятичным знаком.
MS SQL выдает следующее:
1) PLOSH = 1.15
ROUND(PLOSH,1) = 1.1 , аналогично CONVERT(decimal(n,1),PLOSH)
2) PLOSH = 1.65 ...... -> 1.6
и далее ... совершенно непредсказуемые результаты. Еще добавлю, что подобная
абракадабра суммируется.
Какие будут соображения?

With best regards,
Petr


Alexei Savitski

unread,
Dec 16, 1998, 3:00:00 AM12/16/98
to
Приветствую, Petr!

15 Dec 98, Petr Ageev writes to All:
PA> Требуется получать округленные значения с одним десятичным знаком. MS SQL
PA> выдает следующее: 1) PLOSH = 1.15 ROUND(PLOSH,1) = 1.1 , аналогично
PA> CONVERT(decimal(n,1),PLOSH) 2) PLOSH = 1.65 ...... -> 1.6 и далее ...
convert(decimal(n,1),plosh+0.49999999) ;)

PA> подобная абракадабра суммируется. Какие будут соображения?
А какой тип у PLOSH?
Пока-пока, Alexei

... http://postman.ru/~alis

Aleksey Panshin

unread,
Dec 17, 1998, 3:00:00 AM12/17/98
to

Hi, Petr!

>Имеем числовое поле PLOSH типа real или decimal(n,2), что пофигу. Требуется


>получать округленные значения с одним десятичным знаком.

>MS SQL выдает следующее:
>1) PLOSH = 1.15
>ROUND(PLOSH,1) = 1.1 , аналогично CONVERT(decimal(n,1),PLOSH)


>2) PLOSH = 1.65 ...... -> 1.6

>и далее ... совершенно непредсказуемые результаты. Еще добавлю, что

подобная
>абракадабра суммируется.
>Какие будут соображения?

Ну не используй тип real в таких местах - кстати, с чего ты решил, что real
или decimal это пофигу?
Вот скрипт - выполни посмотри на результаты - все станет понятно ( MS SQL
6.5)


declare @a decimal(10,2)
declare @b real

select @a = 1.65
select @b = 1.65

select round(@a,1)
select round(@b,1)
select round(Convert(decimal(10,2),@b),1)

так что с округлением decimal у MS все нормально. А с real действительно
забавно получается.

WBR Lesha(le...@mega.ru)

Petr Ageev

unread,
Dec 17, 1998, 3:00:00 AM12/17/98
to
Hello Alexei!

16 Dec 98 20:36, Alexei Savitski wrote to Petr Ageev:

AS> convert(decimal(n,1),plosh+0.49999999) ;)

Да нет, добавлять в данном конкретном случае надо 0.009

AS> А какой тип у PLOSH?

decimal(7,2).
Вопрос можно поставить и так: мне наплевать на то, как Intel производит
округления в своих процессорах, т.к. я использую конкретный front-end -
MS SQL - а вот он просто обязан исходить из общепринятых правил округления.
Если бы я был лиценционно девственен, то неприменно затеял против Билла
инпичмент.
With best regards,
Petr


Petr Ageev

unread,
Dec 17, 1998, 3:00:00 AM12/17/98
to
Hello Aleksey!

17 Dec 98 12:43, Aleksey Panshin wrote to All:

AP> select round(Convert(decimal(10,2),@b),1)

Спасибо!!!!
Меня хватило только на CONVERT(DECIMAL(10,1),@b).
With best regards,
Petr


Petr Ageev

unread,
Dec 17, 1998, 3:00:00 AM12/17/98
to
Hello Alexei!

16 Dec 98 20:36, Alexei Savitski wrote to Petr Ageev:

AS> convert(decimal(n,1),plosh+0.49999999) ;)

Да нет, добавлять в данном конкретном случае надо 0.009

AS> А какой тип у PLOSH?

real.
With best regards,
Petr


Serge Tarasov

unread,
Dec 18, 1998, 3:00:00 AM12/18/98
to
Доброго дня !
Petr Ageev wrote in message <9137...@p25.f175.n5030.z2.ftn>...

>Имеем числовое поле PLOSH типа real или decimal(n,2), что пофигу. Требуется
>получать округленные значения с одним десятичным знаком.
>MS SQL выдает следующее:
>1) PLOSH = 1.15
>ROUND(PLOSH,1) = 1.1 , аналогично CONVERT(decimal(n,1),PLOSH)
>2) PLOSH = 1.65 ...... -> 1.6
>и далее ... совершенно непредсказуемые результаты. Еще добавлю, что
подобная
>абракадабра суммируется.
>Какие будут соображения?


Проверил на MS SQL 6.5:
declare @f float
select @f = 1.65
select @f, round( @f, 1)

выдает:

------------------------ ------------------------
1.65 1.6
^^^^^ !!!!!!!!! а должно быть 1.7
(1 row(s) affected)

Проверил на Sybase ASE 11.5:
declare @f float
select @f = 1.65
select @f, round( @f, 1)

выдает:

------------------------ ------------------------
1.6499999999999999999 1.7

(1 row(s) affected)

Вывод: M$ делает очередную жопу своим юзерам.
Переходим потихоньку на Сайбазу, больших проблем пока не возникало.


With best wishes
Serge Tarasov
Ontario System project's chief engineer
GSK Audit Ltd., SPb, Russia
e-mail wo...@nnz.ru wo...@gskaudit.spb.ru
ICQ UIN 1365228

Бибер И. Е.

unread,
Dec 18, 1998, 3:00:00 AM12/18/98
to

Petr Ageev пишет в сообщении <9139...@p25.f175.n5030.z2> ...

> AS> А какой тип у PLOSH?
>
>real.

real и decimal - фигня.
Пользуйся float и money.

Igor Biber.vcf

Aleksey Panshin

unread,
Dec 18, 1998, 3:00:00 AM12/18/98
to
Hi, Бибер И. Е.!

Transact SQL Help

The precision of the float datatype uses less storage space for different
ranges of precision. For example, consider the following declaration of
float (n):

Declare @mf float(n)


These are the ranges of precision values permitted.

Where n = Version 6.0 and earlier Version 6.5
1-7 real, 4 bytes real, 4 bytes
8-15 float, 8 bytes real, 4 bytes
16-23 float, 8 bytes real, 4 bytes
24-53 float, 8 bytes float, 8 bytes

WBR Lesha (le...@qua.ru)

Alexey Kopernick

unread,
Dec 19, 1998, 3:00:00 AM12/19/98
to
Hello Serge!

Fri Dec 18 1998 13:24, Serge Tarasov wrote to All:

ST> Проверил на MS SQL 6.5:
ST> declare @f float
ST> select @f = 1.65
ST> select @f, round( @f, 1)
ST> выдает:
ST> -+--+--+--+--+--+--+--+- -+--+--+--+--+--+--+--+-
ST> 1.65 1.6
ST> ^^^^^ !!!!!!!!! а должно быть 1.7

ST> Проверил на Sybase ASE 11.5:
ST> declare @f float
ST> select @f = 1.65
ST> select @f, round( @f, 1)
ST> выдает:
ST> -+--+--+--+--+--+--+--+- -+--+--+--+--+--+--+--+-
ST> 1.6499999999999999999 1.7
ST> Вывод: M$ делает очередную жопу своим юзерам.
ST> Переходим потихоньку на Сайбазу, больших проблем пока не возникало.

Hу я вот тоже решил проверить... MS SQL 6.5:


declare @f float
select @f=1.65
select @f, round(@f,1)

select @f=1.75
select @f, round(@f,1)

------------------------ ------------------------
1.65 1.6

------------------------ ------------------------
1.75 1.8

Итак, кто делает жопу своим юзерам? MS? Или все-таки Sybase, разработчики
которого похоже даже в школе не учились.

Округляется в сторону ближайшей четной цифры. Этому еще в школе учат :)
а вот когда 1.649999999 превращается в 1.7 ну это уже просто шик :)

Alexey [ICQ:3150119]
E-mail: a...@gs707.com


Evgeny Ananyev

unread,
Dec 19, 1998, 3:00:00 AM12/19/98
to
■ Привет, Petr!

17 Dec 98 19:59, Petr Ageev сообщил Alexei Savitski:

PA> Вопрос можно поставить и так: мне наплевать на то, как Intel
PA> производит округления в своих процессорах, т.к. я использую
PA> конкретный front-end - MS SQL - а вот он просто обязан исходить из
PA> общепринятых правил округления.
Что я вижу! Какие пpелестные гpабли! А я-то гpешным делом в подобной
ситуации pешил, что сам умом тpонулся, или плохо в школе/технаpе/институте
учился, да все на пpогpамеpа, да еще везде на "отлично"... Ж%(

А вылезло о чего: M$ Access 2.0, некий глюкавый комплекс на нем, по сети
pаботает :(тоpмозит веpнее) и там надо счет-фактуpу печатать да иногда платежку
к ней. Hу знамо дело, из базы тяну сумму (фактуpы хpанятся, а платежки -- нет)
да фоpмиpую отчет. Только ногами не бейте, эту базу и комплекс не я стpоил, я
этих гоpе-писателей и сам бы с удовольствием четвеpтовал, да они ведь, гады, из
нашей вышестоящей контоpы ее спуcкают:((( Коpоче, все деньги хpанятся в базе как
duble float. Хотя я _нигде_никогда_не_видел_ ни одного платежного документа с
точностью _выше_2-х_ десятичных знаков после запятой! Hа кой их так хpанить?
Однако полномочий чего-то кpупно менять в базе (все платежи по э/энеpгии целого
pайона за несколько лет) я не имею:(

Hу и гpабли есте. В фактуpе одни копейки -- в платежке дpугие:( Все Access-
стандаpтные способы огpаничения точности пеpепpобовал: в таблице так, в отчете
фиг:( Смешно ведь, людей спpашиваю, напpимеp: "200.324999 pублей -- это все еще
32 копейки или уже 33?" Вот HекpоСофт думает, что 33... И как назло, ноpмальной
функции окpугления встpоенной в Access нету -- пpишлось свою pисовать, котоpая
сечет конкpетно больше чем 0.0049999 в большую стоpону (плевать куда, лишь бы в
комплекте фактуpа-платежка одинаково). Да на долбаном Access Basic, а с ним-то
запpосы ваще тоpмозят жутко:(((

А тут оказывается и M$ SQL этим гpешит... Они чего, все девятки по-очеpеди с
конца подбивают, чтоб пpедпоследнюю пятеpку получить для окpугления? А в каком
это классе у нас окpугления пpоходят? Что в начальной школе это точно.

PA> Если бы я был лиценционно девственен, то неприменно затеял против
PA> Билла инпичмент.
Да вpоде у нас этот стаpенький M$ Access куплен, но что толку? HТя (тоже
свеpху спустили) мне pазок базу гpохнула (NTFS загнулся), аппетиты и тоpмоза
жуткие, глюков немеpяно -- нафиг-нафиг, я уже DB2/2 ищу... Шефов убеждать.

P.S. А еще фокус хотите? Иногда пpи доступе этим Access-ом к базе на сеpвеpе
сетка глюкнет (не важно по какому поводу), и вот маздай'95 выбpасывает флаги
типа "Ошибка на устpойстве сети. Повтоpить/отменить?" -- дык вот, эти пимпы
можно отменять и повтоpять до посинения, а выход один -- аппаpатный Reset :(((
Пpедставляете -- кто-то каблуком на коаксиал наступил или там теpминатоp задел
-- и 20 тачек пеpегpужать, а? Scandisk по полной пpогpамме?

║▌█│║▐║█▐║▌║║ Sincerely, Evgeny Ananyev AKA Ansy Anansy.
║▌█│║▐║█▐║▌║║
7║34763║37465║;) [Team OS/2] [Team DOS Navigator]


Tolik Tentser

unread,
Dec 20, 1998, 3:00:00 AM12/20/98
to
Hi Serge Tarasov!

В чреве акулы, пойманной 18 Dec 1998 13:24:09 +0300,
дети капитана Гранта нашли письмо на тему 'Re: Что-то мне становится
нехорошо':

>Проверил на MS SQL 6.5:

>declare @f float
>select @f = 1.65

>select @f, round( @f, 1)
>

>выдает:
>
>------------------------ ------------------------
>1.65 1.6

> ^^^^^ !!!!!!!!! а должно быть 1.7


До кучи то же на 7.0 Beta3

---------------------- ---------------------------
1.6499999999999999 1.6000000000000001

Похоже вот и разгадка (но не оправдание)
он 1.65 округляет до 1.6499999999999999 при
вводе, ну а дальше все почти правильно

Впрочем с DECIMAL:

declare @f DECIMAL(15,2)
select @f = 1.65


select @f, round( @f, 1)

----------------- -----------------
1.65 1.70

С MONEY тоже все корректно, выдает 1.7

Bye ...
Тенцер А.Л.
to...@katren.nsk.ru
ICQ 15925834

Alexei Savitski

unread,
Dec 20, 1998, 3:00:00 AM12/20/98
to
Приветствую, Alexey!

19 Dec 98, Alexey Kopernick writes to Serge Tarasov:
ST>> 1.6499999999999999999 1.7
AK> Hу я вот тоже решил проверить... MS SQL 6.5:

AK> 1.65 1.6
AK> 1.75 1.8

AK> Округляется в сторону ближайшей четной цифры. Этому еще в школе учат
AK> :)
AK> а вот когда 1.649999999 превращается в 1.7 ну это уже просто шик :)

Мораль: money?

Ilya V. Zvyagin

unread,
Dec 21, 1998, 3:00:00 AM12/21/98
to
Tolik Tentser <to...@katren.nsk.ru> записано в статью
<367ce169.7939713@news>...

> >Проверил на MS SQL 6.5:
> >declare @f float

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

> Похоже вот и разгадка (но не оправдание)
> он 1.65 округляет до 1.6499999999999999 при
> вводе, ну а дальше все почти правильно
>
> Впрочем с DECIMAL:
>
> declare @f DECIMAL(15,2)
> select @f = 1.65
> select @f, round( @f, 1)
>
> ----------------- -----------------
> 1.65 1.70

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

Если заменить float на любой формат с фиксированной точкой (разницу-то
чувствуете ?), то все будет OK.

Вообще от FLOAT нельзя ожидать никакой абсолютной точности.

Напр.

10000000000. + 0.0000000000001 почти наверняка будет = 10000000000.

Чего возмущаетесь-то ?


Serge Tarasov

unread,
Dec 21, 1998, 3:00:00 AM12/21/98
to
Доброго дня !

>Если заменить float на любой формат с фиксированной точкой (разницу-то
>чувствуете ?), то все будет OK.
>Вообще от FLOAT нельзя ожидать никакой абсолютной точности.
>Чего возмущаетесь-то ?

Никто и не ожидает от float фиксированнгой точности.
Для этого существуют функции округления. Они-то и должны предоставлять и
обеспечивать необходимую точность. Проанализировать тип аргумента, я думаю в
интерпретаторе SQL, не проблема. Но M$ сделал эту проверку проблемой
конечного юзера.

Serge Tarasov

unread,
Dec 21, 1998, 3:00:00 AM12/21/98
to
Доброго дня !
Alexey Kopernick wrote in message <9141...@f221.n5020.z2.ftn>...
Для тех, кто не понял.

> ST> Проверил на MS SQL 6.5:
> ST> declare @f float
> ST> select @f = 1.65
> ST> select @f, round( @f, 1)
> ST> выдает:
> ST> -+--+--+--+--+--+--+--+- -+--+--+--+--+--+--+--+-
> ST> 1.65 1.6

^^^^ это обман зрения, на самом деле в базе сидит 1.64(9)


> ST> Проверил на Sybase ASE 11.5:
> ST> declare @f float
> ST> select @f = 1.65
> ST> select @f, round( @f, 1)
> ST> выдает:
> ST> -+--+--+--+--+--+--+--+- -+--+--+--+--+--+--+--+-
> ST> 1.6499999999999999999 1.7

^^^^^ это честный показ. Однако у Sybase хватает ума понять, что
раньше (до помещения значения в базу) это было фиксированное число 1.65

>Hу я вот тоже решил проверить... MS SQL 6.5:
>declare @f float


>select @f=1.65
>select @f, round(@f,1)
>select @f=1.75
>select @f, round(@f,1)
>
>------------------------ ------------------------
>1.65 1.6
>
>------------------------ ------------------------
>1.75 1.8
>
>Итак, кто делает жопу своим юзерам? MS? Или все-таки Sybase, разработчики
>которого похоже даже в школе не учились.
>

>Округляется в сторону ближайшей четной цифры. Этому еще в школе учат :)
Это в какой же школе ?
Посмотри учебник арифметики за 4 класс. Или Дума приняла закон об округлении
дробей до ближайшей четной цифры ?


>а вот когда 1.649999999 превращается в 1.7 ну это уже просто шик :)

Я уже сказал, что 1.64 и 9 в периоде это для нормального человека 1.65

Vitaly Fedoriv

unread,
Dec 21, 1998, 3:00:00 AM12/21/98
to
Hello Alexey.

19 Dec 98 22:39, Alexey Kopernick wrote to Serge Tarasov:

AK> Итак, кто делает жопу своим юзерам? MS? Или все-таки Sybase,
AK> разработчики которого похоже даже в школе не учились.

AK> Округляется в сторону ближайшей четной цифры. Этому еще в школе учат
AK> :) а вот когда 1.649999999 превращается в 1.7 ну это уже просто шик :)

Вы это, чего споpите то ?
Hе нpавится pабота стандаpтной функции - пишите свою, котоpая будет окpуглять
так, как надо вам.


Vitaly


Петр В. Мацейканец

unread,
Dec 22, 1998, 3:00:00 AM12/22/98
to
On Sat, 19 Dec 98 21:29:43 +0300, Evgeny Ananyev
<Evgeny....@p17.f201.n5011.z2.fidonet.org> wrote:

[skip]


> А вылезло о чего: M$ Access 2.0, некий глюкавый комплекс на нем, по сети
>pаботает :(тоpмозит веpнее) и там надо счет-фактуpу печатать да иногда платежку
>к ней. Hу знамо дело, из базы тяну сумму (фактуpы хpанятся, а платежки -- нет)
>да фоpмиpую отчет. Только ногами не бейте, эту базу и комплекс не я стpоил, я
>этих гоpе-писателей и сам бы с удовольствием четвеpтовал, да они ведь, гады, из
>нашей вышестоящей контоpы ее спуcкают:((( Коpоче, все деньги хpанятся в базе как
>duble float. Хотя я _нигде_никогда_не_видел_ ни одного платежного документа с
>точностью _выше_2-х_ десятичных знаков после запятой! Hа кой их так хpанить?
>Однако полномочий чего-то кpупно менять в базе (все платежи по э/энеpгии целого
>pайона за несколько лет) я не имею:(
>

[skip]
Может быть поможет следующее -- используй в запросе функцию Format.
Пример:
SELECT a.id, a.sm, Format(a.sm, "0.00")
FROM Sample AS a;

id sm Expr1002
1 1.12145 1.12
2 1.12245 1.12
3 1.12345 1.12
4 1.12445 1.12
5 1.12545 1.13
6 1.12645 1.13
7 1.12745 1.13
8 1.12845 1.13
9 1.12945 1.13
Вроде округляет туда куда нужно.

Origin: Better burn out than fade away...
Петр В. Мацейканец (pe...@center.kamchatka.ru)


Ilya V. Zvyagin

unread,
Dec 22, 1998, 3:00:00 AM12/22/98
to
Serge Tarasov <wo...@exch.nnz.spb.su> записано в статью
<75m4j3$b0p$1...@news.wplus.spb.ru>...

> Никто и не ожидает от float фиксированнгой точности.
> Для этого существуют функции округления. Они-то и должны предоставлять и
> обеспечивать необходимую точность. Проанализировать тип аргумента, я
думаю в
> интерпретаторе SQL, не проблема. Но M$ сделал эту проверку проблемой
> конечного юзера.

Сергей, ну хоть ты-то понимаешь, что НЕ МОЖЕТ быть во float ТОЧНОГО
ЗНАЧЕНИЯ ?
Поэтому результат операции округления, как и любой другой операции, НЕ
МОЖЕТ БЫТЬ
верным в смысле абсолютного математического равенства.

Ilya V. Zvyagin

unread,
Dec 22, 1998, 3:00:00 AM12/22/98
to

Evgeny Ananyev <Evgeny....@p17.f201.n5011.z2.fidonet.org> записано в
статью <9141...@p17.f201.n5011.z2.fidonet.ftn>...

> Что я вижу! Какие пpелестные гpабли! А я-то гpешным делом в подобной
> ситуации pешил, что сам умом тpонулся, или плохо в
школе/технаpе/институте
> учился, да все на пpогpамеpа, да еще везде на "отлично"... Ж%(

> А вылезло о чего: M$ Access 2.0, некий глюкавый комплекс на нем, по
сети
> pаботает :(тоpмозит веpнее) и там надо счет-фактуpу печатать да иногда
платежку
> к ней. Hу знамо дело, из базы тяну сумму (фактуpы хpанятся, а платежки --
нет)
> да фоpмиpую отчет. Только ногами не бейте, эту базу и комплекс не я
стpоил, я
> этих гоpе-писателей и сам бы с удовольствием четвеpтовал, да они ведь,
гады, из
> нашей вышестоящей контоpы ее спуcкают:((( Коpоче, все деньги хpанятся в
базе как
> duble float. Хотя я _нигде_никогда_не_видел_ ни одного платежного
документа с
> точностью _выше_2-х_ десятичных знаков после запятой! Hа кой их так
хpанить?

Чему же учили - то тебя ? Деньги во float хранить ? А что два float-а
сравнивать нельзя не учили ?

> А тут оказывается и M$ SQL этим гpешит... Они чего, все девятки
по-очеpеди с
> конца подбивают, чтоб пpедпоследнюю пятеpку получить для окpугления? А в
каком
> это классе у нас окpугления пpоходят? Что в начальной школе это точно.

Представления чисел в ЭВМ и двоичную арифметику мы проходили на втором
курсе
ВЫСШЕГО УЧЕБНОГО ЗАВЕДЕНИЯ.
Я, конечно, не знаю, где учились те, кто писал твою программу, но ни один
нормальный человек
ДЕНЬГИ в число с плавающей точкой не запихнет.

А раз щзапихнули - то и получили.

Ну а MS, конечно, глюкало, маст дай, и Гейтса вешать надо и тортами
закидать,
а самому на ORACLE под UNIXом - и там тоже деньги во float :-)


Crimean

unread,
Dec 22, 1998, 3:00:00 AM12/22/98
to
Как показывает опыт, для коммерческих приложений более, чем достаточно (для
работы с деньгами, ессно)ДВУХ типов данных: int + money. И никаких траблов,
если не забывать писать round( MyMoney, 2 ). А любителей float вместе с
любителями DDMMYY (две вечно противоборствующих партии) надо... (каждый,
небось, для себя этот вопрос уже не один раз решал ;))))))))


Denis Nekrasov

unread,
Dec 22, 1998, 3:00:00 AM12/22/98
to
Hello Tolik!

Воскpесенье Декабрь 20 1998 08:50, Tolik Tentser wrote to All:

TT> До кучи то же на 7.0 Beta3

TT> -+--+--+--+--+--+--+-- -+--+--+--+--+--+--+--+--+-
TT> 1.6499999999999999 1.6000000000000001

TT> Похоже вот и разгадка (но не оправдание)
TT> он 1.65 округляет до 1.6499999999999999 при
TT> вводе, ну а дальше все почти правильно
старые шутки из си

Round(Number+0.0000000005)
^^^^^^^ подбирается по задаче


Denis


Petr Ageev

unread,
Dec 22, 1998, 3:00:00 AM12/22/98
to
Hello Alexey!

19 Dec 98 22:39, Alexey Kopernick wrote to Serge Tarasov:

AK> Округляется в сторону ближайшей четной цифры. Этому еще в школе учат :)
AK> а вот когда 1.649999999 превращается в 1.7 ну это уже просто шик :)

Это не катит, т.к. тогда не объяснить, почему во вводимых данных (REAL)
последняя пятерка для 1.05, 1.15, 1.55, 1.65 превращается в х.х49999999, т.е.
округляется в меньшую сторону.
With best regards,
Petr


Serge Tarasov

unread,
Dec 23, 1998, 3:00:00 AM12/23/98
to
Доброго дня !
Crimean wrote in message <75o3dg$kb0$1...@dipt.donbass.net>...

>Как показывает опыт, для коммерческих приложений более, чем достаточно (для
>работы с деньгами, ессно)ДВУХ типов данных: int + money. И никаких траблов,
>если не забывать писать round( MyMoney, 2 ).
Романтик ты ;-))
А вещественный (не целочисленный !) склад в чем вести ? В decimal ? Не
хорошо.
Все прекрасно работает во float. И сравнивается замечательно с применением
округления. Если бы не эта ошибка в M$, то можно было вообще жить спокойно.

>А любителей float вместе с
>любителями DDMMYY (две вечно противоборствующих партии) надо... (каждый,
>небось, для себя этот вопрос уже не один раз решал ;))))))))

Погорячился ты слегка ;-) Пусть каждый сам отвечает за свои ошибки.

Serge Tarasov

unread,
Dec 23, 1998, 3:00:00 AM12/23/98
to
Доброго дня !
Ilya V. Zvyagin wrote in message <01be2d99$4da2e580$a50800c0@dream>...
Я согласен.
Я имел в виду другое.
Допустим, у меня есть склад с вещественными показателями количества. Тогда я
имею полное право сравнивать некоторую константу с округленным до нужной
точности количеством товара.
То есть if ( round( @Quantity, 1 ) = 1.7 )
Но из-за досадной "неточности" в M$, я получу не совсем то, что ожидал.
Конечно, тысячные доли можно и не учитывать, но прецедент неприятный.

Ivan Frolcov

unread,
Dec 23, 1998, 3:00:00 AM12/23/98
to
Serge Tarasov (wo...@exch.nnz.spb.su) wrote:
> Я имел в виду другое.
> Допустим, у меня есть склад с вещественными показателями количества.
"На складе имеется e тонн калийных и pi тонн прочих удобрений"...

Crimean

unread,
Dec 23, 1998, 3:00:00 AM12/23/98
to
>>Как показывает опыт, для коммерческих приложений более, чем достаточно
(для
>>работы с деньгами, ессно)ДВУХ типов данных: int + money. И никаких
траблов,
>>если не забывать писать round( MyMoney, 2 ).
>Романтик ты ;-))
>А вещественный (не целочисленный !) склад в чем вести ? В decimal ? Не
>хорошо.
>Все прекрасно работает во float. И сравнивается замечательно с применением
>округления. Если бы не эта ошибка в M$, то можно было вообще жить спокойно.
>

А в чем ты на складе товар учитываешь? (Или скрепки на небалансовом счете, в
долях пачки или в штуках-пачках?) В единицах измерения или в "чем-то", что
отражает "физическую сущность вещей"? По-моему вся бухгалтерия ведется
именно в "единицах измерения", то есть, приняв для этого товара единицой
измерения 1/1000000 долю чего-то ты спокойненько обойдешься int'ом!

А вот с float, особенно с большими числами (или с большими дробями) проблемм
не оберешься. Другое дело - бизнес-типы, которые иногда вообще в BCD или в
"натуральном" виде обрабатываются с отбрасыванием (теоремка какая-то есть по
этому поводу ;) незначащих цифр, "портящих" точность вычислений.
Вот!

Ilya V. Zvyagin

unread,
Dec 23, 1998, 3:00:00 AM12/23/98
to

Serge Tarasov <wo...@exch.nnz.spb.su> записано в статью

<75qfbi$qt$1...@news.wplus.spb.ru>...


> Доброго дня !
> Crimean wrote in message <75o3dg$kb0$1...@dipt.donbass.net>...

> >Как показывает опыт, для коммерческих приложений более, чем достаточно
(для
> >работы с деньгами, ессно)ДВУХ типов данных: int + money. И никаких
траблов,
> >если не забывать писать round( MyMoney, 2 ).
> Романтик ты ;-))
> А вещественный (не целочисленный !) склад в чем вести ? В decimal ? Не
> хорошо.

И чем же это тебе DECIMAL или NUMERIC не угодил ?

> Все прекрасно работает во float. И сравнивается замечательно с
применением
> округления. Если бы не эта ошибка в M$, то можно было вообще жить
спокойно.

Еще раз - это не ошибка.
А склад такой - на float - будет "работать" нормально до первой потери
точности.


Ilya V. Zvyagin

unread,
Dec 23, 1998, 3:00:00 AM12/23/98
to

Serge Tarasov <wo...@exch.nnz.spb.su> записано в статью
<75qfjv$1eo$1...@news.wplus.spb.ru>...

Слушайте, ну что, офигели, что ли все, в детский сад всем, или за парту ?
Ну хоть в школе (высшей) численные методы-то проходили ?
Или я один такой , осчастливленный ?

> То есть if ( round( @Quantity, 1 ) = 1.7 )
> Но из-за досадной "неточности" в M$, я получу не совсем то, что ожидал.
> Конечно, тысячные доли можно и не учитывать, но прецедент неприятный.

НЕЛЬЗЯ сравнивать на равенство число в формате float.

Поскольку @Quantity float, то round(@Quantity,1) будет тоже float, и этот
оператор надо писать
не иначе, как

if abs( round( @Quantity, 1 ) - 1.7 ) < epsilon

, где epsilon - какая-то малая величина, оценивающая порог значимости.

Ilya V. Zvyagin

unread,
Dec 23, 1998, 3:00:00 AM12/23/98
to
Ivan Frolcov <fro...@omega.fintech.ru> записано в статью
<75qipb$c...@omega.fintech.ru>...

> Serge Tarasov (wo...@exch.nnz.spb.su) wrote:
> > Допустим, у меня есть склад с вещественными показателями количества.
> "На складе имеется e тонн калийных и pi тонн прочих удобрений"...

:-) :-) :-) :-) :-) :-) :-) :-) :-)

Да, тут недавно вся эха дружно улыбалась по поводу float в PRIMARY KEY.

Странно, почему она отказывается дружно делать то же самое по поводу денег
во float.

:-)

Anatoly Kuznetsov

unread,
Dec 23, 1998, 3:00:00 AM12/23/98
to
Hello Crimean!

Tuesday December 22 1998 15:31, Crimean wrote to All:

C> Как показывает опыт, для коммерческих приложений более, чем достаточно (для
C> работы с деньгами, ессно)ДВУХ типов данных: int + money. И никаких траблов,
C> если не забывать писать round( MyMoney, 2 ).

Hедостаточно. Проценты и курсы валют требуют точности минимум в четыре
знака после запятой.


Bst.Rgds.TLK. - MailTo:t...@nbd.kis.ru


Evgeny Ananyev

unread,
Dec 23, 1998, 3:00:00 AM12/23/98
to
■ Привет, Ilya!

22 Dec 98 13:55, Ilya V. Zvyagin сообщил All:

IZ> Чему же учили - то тебя ? Деньги во float хранить ?
Пpосто пpоцитиpую себя же:
EA>> Только ногами не бейте, эту базу и комплекс не я стpоил, я этих
^^^^^^^^^^^^^^^^^^^^!!^^^^^^^^^
EA>> гоpе-писателей и сам бы с удовольствием четвеpтовал, да они ведь,
EA>> гады, из нашей вышестоящей контоpы ее спуcкают:((( Коpоче, все
EA>> деньги хpанятся в базе как duble float. Хотя я _нигде_никогда_
EA>> _не_видел_ ни одного платежного документа с точностью _выше_2-х_
EA>> десятичных знаков после запятой! Hа кой их так хpанить?
Внимательнее читайте, пожалуйста... В эту контоpу я устpоился год назад,
когда за 2 года уже записей этих в базе было -- в том-то и фишка, что откатить
тpудно... Они в столице сидят, а мне pасхлебывать да юзеpам глюки БД чистить:(

IZ> А что два float-а сравнивать нельзя не учили ?
Меня учили. Тех, кто базу создавал и pазpабатывал -- навеpное, плохо :(
А еще они pазносят оплату, наpываются на _неполное_ ее погашение (патамучта
float!) и отдельным сообщеньицем пpедлагают юзеpу ввести почти ту же сумму,
только с вполне конкpетным числом девяток точности. _КАКОВО_ ? Ж%[.....]

Вешать однозначно!

IZ> Представления чисел в ЭВМ и двоичную арифметику мы проходили на втором
IZ> курсе ВЫСШЕГО УЧЕБHОГО ЗАВЕДЕHИЯ.
Hу, особо интеpесующиеся начинали с систем счисления еще в школе ;) А вот
задачки повышенной сложности из Еpшовского учебника сдавали на ассемблеpе EC
ЭВМ. Это мой пеpвый _pабочий_ язык, втоpым был PL/I. Hе жалели детей в технаpе,
сpазу после восьмого класса ;(

IZ> Я, конечно, не знаю, где учились те, кто писал твою программу,
Самое печальное, что ВУЗ тот же, где и я. Hо двумя годами позже. Жалко мне
нашу дегpадиpующую систему высшего обpазования:( PC-шники глупые выходят...

IZ> ни один нормальный человек ДЕHЬГИ в число с плавающей точкой
IZ> не запихнет.
А я о чем? Вывод: эти гоpе-pазpаботчики -- люди неноpмальные. И SQL-я они
шаpахаются, как чеpт ладана -- пpивыкли мышой pисовать в фоpмочках. Hо мне от
этого не легче, для меня они вышестоящая оpганизация, а на пpоге этой кpивой
завязана вся pабота отделения. И на всю контоpу -- я один компутеpщик.

IZ> А раз запихнули - то и получили.
Вопpос: как выпихнуть? Там они еще и логику pазноса оплаты чеpез float
закpутили. Hапpимеp, пpиходит в банк столько-то денег оплаты. Имеется некое
число выставленных сумм (счет-фактуp) но не точно на сумму оплаты, есте. Hадо
pаспpеделить на несколько фактуp, по каким-то пpавилам. Hу вот, и тут, млин, они
задействуют какие-то левые float-доли, пеpемножают на них суммы, и т.п..
Уpодство...

Hет чтобы с какой-то фактуpы начинать заполнять (списывать) оплату, пока она
еще есть, закpылась фактуpа -- давай следующую незакpытую... А сейчас уже ~ два
десятка тысяч записей подшито в бумагах и пpошло по банкам -- юp.документы...

IZ> Hу а MS, конечно, глюкало, маст дай, и Гейтса вешать надо и тортами
IZ> закидать,
Гуталиновыми. Подписываюсь.

IZ> а самому на ORACLE под UNIXом
Мне бы чего freeware, да чтоб пpогу пеpенести без больших пеpеделок... Hо
pазве с M$ Access-а пеpенесешь? Имена-то атpибутов киpиллицей, с пpобелами и в
квадpатных скобках. Логика в основном на Васике. Документации и комментаpиев в
пpинципе не велось. Вот пpиспичило, pасшифpовал по коду -- у меня фоpмиpование
отчета стало пpолетать за 20 секунд вместо их 6 минут;) Одним всего запpосом --
вместо их вызова кода на Васике с паpой вложенных в цикл подзапpосов и функций
_на_ _каждую!_ из полутоpа тысяч записей Ж%( ) Hо это ж надо пpосечь спеpва,
чего они хотели получить этим хитpож... умным кодом! Вpемя!!! А кода еще много.

Люди знающие, подскажите, близок ли конец? В смысле, на каком объеме базы (Mb
или записей) M$ Access-у 2.0 смеpтушка пpидет? Сейчас там уже под 20 метpов...
Таблиц штук 30 сильносвязанных, из них штук 5 по 10-20 тыщ записей, остальное
спpавочники. Я уже не говоpю пpо сетевой доступ с 10 pабочих мест...

IZ> - и там тоже деньги во float :-)
Свят-свят! Hафиг такие пpаздники. Мы с Оpакла (КАРС котоpый болгаpский) на
System/360 начинали, а потом уже появился Robotron 1715 и dBaseII ;)

Serge Tarasov

unread,
Dec 24, 1998, 3:00:00 AM12/24/98
to
Доброго дня !
Crimean wrote in message <75qm22$joo$1...@dipt.donbass.net>...

>А в чем ты на складе товар учитываешь? (Или скрепки на небалансовом счете,
в
>долях пачки или в штуках-пачках?) В единицах измерения или в "чем-то", что
>отражает "физическую сущность вещей"? По-моему вся бухгалтерия ведется
>именно в "единицах измерения", то есть, приняв для этого товара единицой
>измерения 1/1000000 долю чего-то ты спокойненько обойдешься int'ом!
Исторический экскурс.
Такие темы не прокатили в проекте изначально.
Склад ведется в так называемых "базовых единицах". Для простоты - это
единицы системы Си - грамм, метр, метр квадратный. А в отгрузках можно
ставить любые "производные единицы" - килограмм, литр, квадратный километр,
погонный метр через соотношения с базовыми.
Это позволяет _очень быстро_ считать склад по операциям и затем "одним
движением" переводить результат в любую производную единицу.
Точность представления является свойством конкретной единицы измерения.
Склад - это более ширококе понятие, нежели место хранения бочек с пивом. Это
некоторый регистр накопления каких-то объектов учета.
Если учитывать в int, то всегда есть проблема, что у заказчика окажется
необходимость считать в еще меньших (или слишком больших) единицах, чем это
предусмотрено. Например, решили сырье в граммах считать - для сталелитейного
производства это пройдет, а для химлаборатории нет. Там в милиграммах надо.
А то и в микро. А int у нас содержит всего-то 2147483647 милиграмм или 2147
килограмма. Маловато 2 тонны для цеха будет.
По тем же причинам не катит decimal - заранее неизвестна необходимая
точность хранения для разных складов. А резервировать 20 знаков после
запятой нехорошо, тем более, что всего их 38.

>А вот с float, особенно с большими числами (или с большими дробями)
проблемм
>не оберешься.

Ну не было проблем. Пока по крайней мере. Пока - это уже второй год пошел.

Serge Tarasov

unread,
Dec 24, 1998, 3:00:00 AM12/24/98
to
Доброго дня !
Ilya V. Zvyagin wrote in message <01be2e8d$a343f980$a50800c0@dream>...

>И чем же это тебе DECIMAL или NUMERIC не угодил ?
Я только что написал это в ответе Crimean'у, там небольшой экскурс в
проектирование.


>> Все прекрасно работает во float. И сравнивается замечательно с
>применением
>> округления. Если бы не эта ошибка в M$, то можно было вообще жить
>спокойно.
>Еще раз - это не ошибка.
>А склад такой - на float - будет "работать" нормально до первой потери
>точности.

Для этого-то и существует округление. Чтобы точность поиметь в нужных для
данного вычисления пределах.

Serge Tarasov

unread,
Dec 24, 1998, 3:00:00 AM12/24/98
to
Доброго дня !
Ilya V. Zvyagin wrote in message <01be2e9d$91d82f80$a50800c0@dream>...

>Слушайте, ну что, офигели, что ли все, в детский сад всем, или за парту ?
>Ну хоть в школе (высшей) численные методы-то проходили ?
>Или я один такой , осчастливленный ?
>> То есть if ( round( @Quantity, 1 ) = 1.7 )
>> Но из-за досадной "неточности" в M$, я получу не совсем то, что ожидал.
>> Конечно, тысячные доли можно и не учитывать, но прецедент неприятный.
>
>НЕЛЬЗЯ сравнивать на равенство число в формате float.
>
>Поскольку @Quantity float, то round(@Quantity,1) будет тоже float, и этот
>оператор надо писать
>не иначе, как
>
>if abs( round( @Quantity, 1 ) - 1.7 ) < epsilon
>
>, где epsilon - какая-то малая величина, оценивающая порог значимости.
>

Зачем приплетать численные методы к простым вычислениям абсолютных
погрешностей (алгебра 6-й класс) ?

Я изменю условия задачи. Уберем round, который у M$ возвращает тот же тип,
что и тип аргумента.

declare @f float
select @f = 1.65
select @f, convert( numeric( 10, 1 ), @f )

(1 row(s) affected)


------------------------ --------------
1.65 1.6
^^^ - а это что за херомантия ? и тип у него
numeric( 10, 1 )