Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / FoxPro, Visual FoxPro Новый топик    Ответить
 неправильно считается сумма.  [new]
denis_viktorovich
Member

Откуда: Екб
Сообщений: 1215
Интересную штуку отловил. Задача на VFP 7 SP1, имеется таблица, в ней есть числовое поле double (8.2), содержимое следующее:
2.71
0.67
3.06
1.47

calculate sum(fld1) TO c1
? c1
Показывает 7.90 вместо ожидаемого 7.91. Кто нибудь знает изз-за чего это и как бороться?
13 мар 08, 14:42    [5405913]     Ответить | Цитировать Сообщить модератору
 Re: неправильно считается сумма.  [new]
PaulWist
Member

Откуда:
Сообщений: 2236
Не верю

CREATE CURSOR test (f1 b(2))

INSERT INTO test (f1) VALUES (2.71)
INSERT INTO test (f1) VALUES (0.67)
INSERT INTO test (f1) VALUES (3.06)
INSERT INTO test (f1) VALUES (1.47)

calculate sum(f1) TO c1
? c1
13 мар 08, 14:49    [5405973]     Ответить | Цитировать Сообщить модератору
 Re: неправильно считается сумма.  [new]
denis_viktorovich
Member

Откуда: Екб
Сообщений: 1215
Если поменять на Numeric то работает.
13 мар 08, 14:50    [5405988]     Ответить | Цитировать Сообщить модератору
 Re: неправильно считается сумма.  [new]
PaulWist
Member

Откуда:
Сообщений: 2236
denis_viktorovich
Если поменять на Numeric то работает.


Не понял, что менять-то, у Вас мой пример выдаёт значение 7.90 ?
13 мар 08, 14:54    [5406034]     Ответить | Цитировать Сообщить модератору
 Re: неправильно считается сумма.  [new]
denis_viktorovich
Member

Откуда: Екб
Сообщений: 1215
Пардон, не обновив топик ответил. Ваш пример нормально работает. Я поменял тип поля на numeric - все стало нормально. Поменял обратно тоже все ОК. Таблицу создаю посредством select * into DBF ...
13 мар 08, 15:00    [5406098]     Ответить | Цитировать Сообщить модератору
 Re: неправильно считается сумма.  [new]
denis_viktorovich
Member

Откуда: Екб
Сообщений: 1215
Т.е. суммироваться адекватно моя таблица начала после того ка я поменял это поле (туда и обратно :-) )
13 мар 08, 15:02    [5406117]     Ответить | Цитировать Сообщить модератору
 Re: неправильно считается сумма.  [new]
Dima T
Member

Откуда:
Сообщений: 15301
denis_viktorovich
...
Кто нибудь знает изз-за чего это и как бороться?

Из-за double. Сделай тип NUMERIC(8.2)

Если кратко: double хранится в двоичном виде с плавающей запятой и при преобразовании того что после запятой 100% точности не получается, ошибка в 7-8 знаке. Вот погрешность и вылазит. Старинная проблема, из-за нее тип CURRENCY (он же MONEY) придумали, двоично-десятичную систему в процессоры добавили.

double можно использовать когда разброс значений огромен, а погрешность не принципиальна, т.е. ошибка в 7-8 знаке. В твоем случае вероятно ошибка накопилась ранее, т.к. пример PaulWist ее не подтверждает.

Твоя смена формата туда-обратно провела пересчет, но проблема вылезет снова. Используй тип NUMERIC(8.2)
13 мар 08, 15:12    [5406204]     Ответить | Цитировать Сообщить модератору
 Re: неправильно считается сумма.  [new]
denis_viktorovich
Member

Откуда: Екб
Сообщений: 1215
Причем при следующем расчете все повторяется. Както интересно файл портится, отображается нормально, а при суммировании обрезает.

К сообщению приложен файл (testtbl.dbf - 400bytes) cкачать
13 мар 08, 15:16    [5406230]     Ответить | Цитировать Сообщить модератору
 Re: неправильно считается сумма.  [new]
denis_viktorovich
Member

Откуда: Екб
Сообщений: 1215
Dima T
denis_viktorovich
...
Кто нибудь знает изз-за чего это и как бороться?

Из-за double. Сделай тип NUMERIC(8.2)

Если кратко: double хранится в двоичном виде с плавающей запятой и при преобразовании того что после запятой 100% точности не получается, ошибка в 7-8 знаке. Вот погрешность и вылазит. Старинная проблема, из-за нее тип CURRENCY (он же MONEY) придумали, двоично-десятичную систему в процессоры добавили.

double можно использовать когда разброс значений огромен, а погрешность не принципиальна, т.е. ошибка в 7-8 знаке. В твоем случае вероятно ошибка накопилась ранее, т.к. пример PaulWist ее не подтверждает.

Твоя смена формата туда-обратно провела пересчет, но проблема вылезет снова. Используй тип NUMERIC(8.2)


Спасибо всем. Пожалуй надо и правда numeric использовать. Интересно, задача не мной написана и почемуто раньше не обращали внимания на это. Век живи, век учись, .....
13 мар 08, 15:21    [5406290]     Ответить | Цитировать Сообщить модератору
 Re: неправильно считается сумма.  [new]
PaulWist
Member

Откуда:
Сообщений: 2236
denis_viktorovich
Причем при следующем расчете все повторяется. Както интересно файл портится, отображается нормально, а при суммировании обрезает.


Вам уже Dima T ответил, что Вы пытаетесь делать мат операции с "приблизительным" типом данных, если нужно точное мат соответствие в мат операциях, тогда надо использовать точные типы данных, либо в самой мат операции использовать точные типы данных.
13 мар 08, 15:21    [5406292]     Ответить | Цитировать Сообщить модератору
 Re: неправильно считается сумма.  [new]
Dima T
Member

Откуда:
Сообщений: 15301
denis_viktorovich
Причем при следующем расчете все повторяется. Както интересно файл портится, отображается нормально, а при суммировании обрезает.

он не портится, это особенность формата double
13 мар 08, 15:24    [5406322]     Ответить | Цитировать Сообщить модератору
 Re: неправильно считается сумма.  [new]
Dima T
Member

Откуда:
Сообщений: 15301
denis_viktorovich
... Интересно, задача не мной написана и почемуто раньше не обращали внимания на это. .....

Раньше техника послабее была, винты поменьше, памяти меньше, сетка 10мбит ... Поэтому всеми способами старались минимизировать объем хранимых данных для повышения производительности. Хотя это и сейчас актуально, может не так сильно. Может разработчик и знал о проблеме, но счел ее менее важной чем снижение производительности.

С NUMERIC тоже можно на копейках попасться:
CREATE CURSOR test (f1 N(5,2))

INSERT INTO test (f1) VALUES (102.71)
INSERT INTO test (f1) VALUES (0.67)
INSERT INTO test (f1) VALUES (3.06)
INSERT INTO test (f1) VALUES (1.47)

calculate sum(f1) TO c1
? c1
ответ будет 107.90, а не 107.91 как ожидается.
Проблема в значении 102.71 оно не влазит в N(5,2) и сохранится как 102.7 и ошибки переполнения никакой при этом не будет.

Для денежных сумм специально придумали еще тип CURRENCY (в MS-SQL MONEY), обрабатывается как восьмибайтное двоичное целое, отображается со сдвигом на 4 десятичных знака, нет никаких погрешностей при сложении, вычитании, умножении, но есть подводные камни при делении (результат до 4-х знаков после запятой округляется). т.е. 1.2345 / 100 * 100 => 1.2300

Надо просто все это знать перед тем как использовать.
13 мар 08, 17:32    [5407350]     Ответить | Цитировать Сообщить модератору
 Re: неправильно считается сумма.  [new]
PaulWist
Member

Откуда:
Сообщений: 2236
Dima T

Проблема в значении 102.71 оно не влазит в N(5,2) и сохранится как 102.7 и ошибки переполнения никакой при этом не будет.


Э-э-э, скорее это не проблема, а "забывчивость", те Вы пытаетесь в 5 знаков 4 цифры+точка запихнуть число из 6-ти знаков.
14 мар 08, 11:00    [5409338]     Ответить | Цитировать Сообщить модератору
 Re: неправильно считается сумма.  [new]
Burn
Member

Откуда: Днепропетровск, Украина
Сообщений: 1167
PaulWist
Э-э-э, скорее это не проблема, а "забывчивость", те Вы пытаетесь в 5 знаков 4 цифры+точка запихнуть число из 6-ти знаков.

Лучше бы он в этой ситуации ошибку генерил и только потом запихивал;)
14 мар 08, 12:18    [5410045]     Ответить | Цитировать Сообщить модератору
 Re: неправильно считается сумма.  [new]
Dima T
Member

Откуда:
Сообщений: 15301
PaulWist
Dima T

Проблема в значении 102.71 оно не влазит в N(5,2) и сохранится как 102.7 и ошибки переполнения никакой при этом не будет.


Э-э-э, скорее это не проблема, а "забывчивость", те Вы пытаетесь в 5 знаков 4 цифры+точка запихнуть число из 6-ти знаков.

Какой ты догадливый Не надо буквально воспринимать примеры, они простые только для того чтобы их легко понять было, проявляй немного фантазии :)

Реально было так (лет десять назад). В проге была оборотная ведомость по покупателям (остаток, отгружено, оплачено), которая предварительно сохранялась в курсор, поля сумм были N(10, 2) т.е. до 10 млн.р. разрядности хватало. И в один прекрасный дель появился контрагент, по которому оборот перевалил за 10 млн.р., копейки обрезались, а т.к. остаток на конец считался как остаток на начало + приход - расход, то этот конечный остаток не совпал с остатком на начало следующего периода (который считался правильно). На 3 копейки, мне тогда главбухша долго эти три копейки забыть не могла, они там отчеты все в налоговую посдавали, дотошная попалась :)

После того случая для денег мне больше тип MONEY нравится.
14 мар 08, 17:52    [5412881]     Ответить | Цитировать Сообщить модератору
Все форумы / FoxPro, Visual FoxPro Ответить