Форум » Clipper » Что бы это значило и как с этим бороться? » Ответить

Что бы это значило и как с этим бороться?

sergey5703: // Программа LOCAL n10 := 10, n3 := 3, n10div3, i n10div3 := (n10 / n3) FOR i := 1 TO n3 n10 := n10 - n10div3 NEXT ? n10 IF n10 == 0 ? "ноль" ELSE ? "не ноль" ENDIF ? // Результат 0.00 не ноль

Ответов - 29, стр: 1 2 All

suv2: Sergy пишет: 2) никогда не использовать усечение усечение, а именно, округление промежуточных результатов - обязательная вещь привожу пример суммируются N числовых полей с 2мя знаками после запятой на каждом шаге необходимо округлять результат до 2го знака иначе накопится ошибка в сумме

suv2: Sergy пишет: 4) выводить результаты усечения в документах в полях "сумма", "итого" и тп - только после того, как с макс. точностью просчитан столбец или строка. учитывая вышесказанное, п.4 неверен

suv2: Sergy пишет: 3) всегда использовать максимально возможную точность в таблицах, 3 минимум, а лучше 4-5 знаков после запятой (для руб/коп) а почему не 10? ))) я могу за тебя ответить. потому если не применяются правильные алгоритмы, то как недостаточная точность, так и избыточная точность приводит тем или иным проблемам. в общем, этот пункт тоже неверен. Копейки прекрасно умещаются в 2 знака, если речь идет о стоимости. И ДОЛЖНЫ умещаться в 2 знака, ибо таковы реалии бухучета. Вряд ли тебя поймут в налоговой, если ты с жаром будешь доказывать, что продал 1шт изделия за 3рубля 33.33333333333333 копейки, потому что ты их покупал 3 штуки за 10 рублей. В данном случае 1е изделие продается за 3.33, второе за 3.34, третье - за 3.33 имеем 3 шт за 10.00 продаем 1шт за RoundTo(10/3,2) == (3.33) остается 2шт и стоят они 10-3.33==6.67 второе изделие при продаже будет стоить RoundTo(6.67/2,2) == 3.335==3.34 (при округлении 5 к четному, равно как и при округлении 5 к большему) и останется одно изделие со стоимостью 3.33, которое прекрасно продастся и останется ровно НОЛЬ на суммовом остатке. А избыточная точность может например привести к тому, что на остатке будет числится 0.000001 изделия (одна миллионная штуки вместо нуля) со стоимостью -0.000000001 руб (минус одна миллиардная рубля) и средней стоимостью МИНУС тысяча рублей за штуку, что приведет к хрен знает к чему, чаще всего к коллапсу системы. Надо просто применять правильные алгоритмы.


les: suv2 пишет: имеем 3 шт за 10.00 обычно в накладной есть колонки "цена", "количество", "сумма". как тут получить 3 шт за 10.00 suv2 пишет: Надо просто применять правильные алгоритмы. согласен! Вот в Excell 2003 есть такая фишка: Сервис->Параметры->Параметры книги->Точность как на экране. Бухам нравится

suv2: les пишет: обычно в накладной есть колонки "цена", "количество", "сумма". как тут получить 3 шт за 10.00 я в курсе, и цифры там двузначные причем. и в чем вопрос?

les: suv2 пишет: и в чем вопрос? какая цена 1 штуки?

suv2: Допустим, речь о закупочной цене. Тебе их продавали как комплект, а ты его разукомплектовал и продаешь поштучо. Допустим, в Уставе прописан учет по средней. Цена одной штуки 3.333333333 (в таком виде закупочная цена будет хранится в таблице), но это вещь вспомогательная, потому что приоритетом является стоимость всех штук, она точнее по определению. В момент продажи лучше закупочная стоимость одной штуки вычисляется точно, округляется до 2х знаков и в таком виде попадает в расходный документ. На складе остается суммовой остаток 10руб за минуом округленного ухода - 6.67, средняя стоимость 1ш будет 3.335 Если речь о продажной цене, то неточностей обычно нет, потому что наценка идет от одной штуки с 2мя точно прописанными знаками. Тем не менее и там бывают случаи, когда из-за применение скидок, стоимость 1 штуки не укладывается точно в 2 знака. Ну и что, она округляется, приоритетом все равно является ИТОГО, а не ЦЕНА

AndreyZh: Добрый день! В последний год часто начались встречаться глюки с "математикой", что заставило переделать множество старых механизмов работы с числами: 1. x:=0; (х==0) даёт .f. Помогает. Empty(x) 2. много лет корректно работал механизм разделения количества на упаковки и штуки. Упаковки u := Int(количество/фасовка); Штуки = количество - (u*фасовка)... Народ стал активно использовать дробные фасовки и стало получаться, например: Фасовка = 5.4 кг. - количество 21.6 разбивает на 3 упаковки + 5.4 штуки, но - количество 27 разбивает на 5 упаковок + 0 штук. Пришлось сменить алгоритм на (помогло) Упаковки Int((количество + 0.00000001)/фасовка); Штуки = Round(количество - (u*фасовка),6) // у меня точность количеств 6 знаков 3. Новая "засада" по вопросу цены/суммы отгрузки и соответственно точности: цена 235.99 * количество 1.072 равно сумма 252.98128 при этом разные функции по разному могут округлять данное значение... Пока ограничился "предупреждением для user"..

suv2: AndreyZh пишет: 1. x:=0; (х==0) даёт .f. x == 0 даёт TRUE. что у тебя за странный клиппер? AndreyZh пишет: Упаковки u := Int(количество/фасовка); Это совершенно неверная формула. Int возвращает то, что получилось при ОТБРАСЫВАНИИ дробной части числа!!!!!! Если у тебя в результате операции деления должно получится целое число 4, но в из-за математических неточностей получилось 3.99999999999999999, то результат Int будет ТРИ, а не 4. Правильная формула для упаковок u:=round(количество/фасовка,0) Ну и кроме того, клиппер (паскаль, ассемблер, процессор) абсолютно точно делит 21.6 на 5.4 и дает РОВНО 4, без всяких там арифметических ошибок, абсолютно целое число (дамп: 00 00 00 00 00 00 10 40), так что наблюдаемые тобой факты опять не подтверждаются. Даже по потенциально неверной формуле Упаковки u := Int(количество/фасовка) мы получим 4 упаковки и ноль штук, а не 3 упаковки и 5.4 штук AndreyZh пишет: 252.98128 при этом разные функции по разному могут округлять данное значение господи, да о чем ты? что тут можно по-разному округлить?



полная версия страницы