Функция округления Окр() странно работает

1. BarsukM 15.01.19 12:02 Сейчас в теме
Функция округления Окр() в 1С77 как-то странно работает.

Окр(482.37 * (20 / 120), 2) = 80.39
тоже самое, но без скобок внутри дает другой результат, хотя вроде не должно.
Окр(482.37 * 20 / 120, 2) = 80.40

Это нормально? Как теперь считать НДС? Со скобками, без?
И почему-то когда ставка НДС была 18% такие косяки не вылезали.
По теме из базы знаний
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. Boneman 298 15.01.19 12:28 Сейчас в теме
(1)
Функция округления Окр() в 1С77 как-то странно работает.

при чем тут функция.
Обычная математика, 5 класс, то что в скобках выполняется первым. А без скобок просто все подряд.
таким образом в первом случае результат
80.39499999
во втором случае
80.395

по правилам округления, берем значение после нужного разряда, и если оно меньше 5 то в меньшую сторону, если 5 и больше то в большую.
Вот и получим 80.39 и 80.40
ivangrant; Anchoret; Infector; +3 Ответить
5. BarsukM 15.01.19 12:54 Сейчас в теме
(2)Ок. Почему тогда в 1с8 работает иначе? Там в обоих примерах получается 80,4.
6. singlych 15.01.19 13:16 Сейчас в теме
(5) может быть, в клюшках меньше знаков после запятой.
потому что 482.37 * 0.166666666666 = 80.394999....
а 482.37 * 0.1666666666666 = 80.395000...
7. Boneman 298 15.01.19 13:33 Сейчас в теме
(5)
Почему тогда в 1с8 работает иначе? Там в обоих примерах получается 80,4.

и опять же проблема не в функции ОКР,
а в самой форме представления чисел с плавающей запятой. Видимо немного по разному там это работает.
в 8.2. результат 482.37 * (20 / 120) = 80,39500000000000000000000016079

Соответственно функция ОКР так и отработает 80.395.
8. SlavaKron 15.01.19 13:55 Сейчас в теме
(7)Да нет, как раз в функции окр 7.7. Это баг. Намного интересней с математической точки зрения, существует ли такая же ошибка для 18/118 на этой платформе.
9. Boneman 298 15.01.19 14:18 Сейчас в теме
(8)
Да нет, как раз в функции окр 7.7. Это баг

в чем баг то ?
Приведите результат вычисления со скобками и без скобок, без применения функции ОКР, в 7.7
тогда уже и будет понятно баг или не баг.
для 8-ки все результаты я привел,
про 7 ку забыл лет 10 назад, поэтому проверить нет возможности.
10. BarsukM 15.01.19 14:26 Сейчас в теме
(9)
Приведите результат вычисления со скобками и без скобок, без применения функции ОКР, в 7.7

482.37 * (20 / 120) = 80.395
482.37 * 20 / 120 = 80.395
11. Boneman 298 15.01.19 14:29 Сейчас в теме
(10) т.е. значения абсолютно одинаковые,
а если их округлить, то получим разные цифры ?
12. BarsukM 15.01.19 14:30 Сейчас в теме
14. Boneman 298 15.01.19 14:36 Сейчас в теме
(12) ну тут я сдаюсь, т.к. 7ку даже щупать негде.
13. spacecraft 15.01.19 14:35 Сейчас в теме
(10) это все навсего уже округление при выводе Сообщить. Именно так ведь проверяли?
Смотрите:
а = 482.37 * (20 / 120) ;
б = 482.37 * 20 / 120;
Сообщить(Окр(а, 2));
Сообщить(Окр(б, 2));

Все еще думаете, что проблема в Окр() ?
27. CheBurator 3119 16.01.19 00:45 Сейчас в теме
(7) или у вас восьмерка кривая, или вы в результате вычислений от руки нулей набабахали в середине дробной части.
3. spacecraft 15.01.19 12:29 Сейчас в теме
(1) с математической точки зрения все правильно :)
482.37 * 20 / 120 = 80.395
482.37 * (20 / 120) = 482.37 * 0,1[6] = максимально приближено к 80.395, но недостает до нее в бесконечности.
4. Boneman 298 15.01.19 12:32 Сейчас в теме
(1)
И почему-то когда ставка НДС была 18% такие косяки не вылезали.

косяки сколько помню, всегда периодически вылазили в расчете НДСов,
бывает даже в документах от поставщика приходят одни цифры, а при оприходовании товара суммы НДС подгоняют. Особенно на мелочевке.
28. CheBurator 3119 16.01.19 00:49 Сейчас в теме
(4) не было никаких "косяков".
все так называемые "косяки" есть следствие прменяемых разных алгоритмов у сторон сделки. ктото считает НДС "от прямого", кто-то "от обратного" (а правила математики с учетом ограничения разрядности цены) и дадут "отклонения" (кто-то еще вдобавок ошибок туда нахренячит по типу задававшихся в этой ветке). для приходных документов если вбивать количество, сумму и суммуНДС - !О, ЧУДО! - никаких отклонений и подгонок не будет. вообще. никогда. то есть совсем.
15. Xershi 1484 15.01.19 14:44 Сейчас в теме
(1) как оказалось по опыту семёрка все считает как надо. Просто нужно понимать контекст и знать настройки программы!
Ваши вычисления на пальцах филькина грамота.
Скрины настроек и отладчика в студию!
16. spacecraft 15.01.19 14:51 Сейчас в теме
(1) вот код для понимания механики вычислений:
а = 482.37 * (20 / 120) ;
б = 482.37 * 20 / 120;
Сообщить("а = "+а);
Сообщить("б = "+б);
Сообщить("Округление а = "+Окр(а, 2));
Сообщить("Округление б = "+Окр(б, 2));
а = а + 0.00000000000000000000001;
б = б + 0.00000000000000000000001;
Сообщить("Новое а = "+а);
Сообщить("Новое б = "+б);
Сообщить("Округление новое а = "+Окр(а, 2));
Сообщить("Округление новое б = "+Окр(б, 2));
Показать

Результат:
а = 80.395
б = 80.395
Округление а = 80.39
Округление б = 80.4
Новое а = 80.395
Новое б = 80.395
Округление новое а = 80.4
Округление новое б = 80.4
BarsukM; Boneman; +2 Ответить
17. SlavaKron 15.01.19 15:13 Сейчас в теме
(16) а = 482.37 * (20 / 120) ;
б = 482.37 * 20 / 120;
Сообщить(а = б);
Что покажет?
18. spacecraft 15.01.19 15:29 Сейчас в теме
(17) а что должно показать? Это не 1с8. В 1с77 булево типа нет.
А так, все правильно показывает:
а = 482.37 * (20 / 120) ;
б = 482.37 * 20 / 120;

Если а = б Тогда
    Сообщить("Равны");
Иначе
	Сообщить("Не равны");
КонецЕсли;
Показать

Результат:
Не равны
20. BarsukM 15.01.19 15:38 Сейчас в теме
(17)

	а = 482.37 * (20 / 120);
	б = 482.37 * 20 / 120;
	Если а = б Тогда
	    Сообщить("Истина");
	иначе
		Сообщить("Ложь. Разница: "+(а - б));
	КонецЕсли;
Показать


Результат:
Ложь. Разница: -0
19. BarsukM 15.01.19 15:36 Сейчас в теме
(16) Ну т.е. Окр() использует число, которое нельзя увидеть. Даже в отладчике. Мутновато.
21. spacecraft 15.01.19 15:39 Сейчас в теме
(19) Окр() оперирует с реальным значением числа. Сообщить и показ в отладчике это строковое представление (конвертация в строку), которое округляется для "лучшего" показа пользователю.
CheBurator; BarsukM; +2 Ответить
22. spacecraft 15.01.19 15:47 Сейчас в теме
(19) разницу можно узнать:
а = 482.37 * (20 / 120) ;
б = 482.37 * 20 / 120;
Сообщить((а-б)*1000000000000000000000000);

Результат:
-0.32158
23. BarsukM 15.01.19 15:55 Сейчас в теме
(22)
Результат:
-0.32158


Результат В 8.3:
+0,16079
24. spacecraft 15.01.19 15:58 Сейчас в теме
(23) это разная максимальная разрядность хранения(использования в вычислениях) числа и соответственно округление. Для чисел, которые не имеют реального конечного результата это нормально.
25. Xershi 1484 15.01.19 16:07 Сейчас в теме
(19) это называется контекст. Произошло неявное преобразование. Это разработчик должен знать, а когда не знает думает что баг! Когда придет понимание особенностей клюшки, тогда глупые вопросы уйдут!
Иногда достаточно справку почитать иногда документацию, а иногда приходится рыть форум и только тогда допирать до сути!
26. CheBurator 3119 16.01.19 00:36 Сейчас в теме
В семерке выводимые в отображение после ЗПТ урезаются до 20 знаков вроде, реально там не помню сколько цифр максимальное дробное представление.
для примера
в отладчике:
(18зн) 482.37*0.166666666666666667 = 80.39500000000000016079
(19зн) 482.37*0.1666666666666666667 = 80.39500000000000001608
(20зн) 482.37*0.16666666666666666667 = 80.39500000000000000161
(21зн) 482.37*0.166666666666666666667 = 80.39500000000000000016
(22зн) 482.37*0.1666666666666666666667 = 80.39500000000000000002
(23зн) 482.37*0.16666666666666666666667 = 80.395
482.37*1000000000*(20/120) = 80394999999.99999999999999967842 //<==== меньше чем 0.395
(482.37*(20/120)-80)*1000000000000 = 394999999999.99999999999967842

если посмотреть на 2 последние строки - то все видно совсем ясно - и отклонение "вниз" от 0.395 как выше правильно указали -0.0.....32158
29. CheBurator 3119 16.01.19 01:04 Сейчас в теме
другое дело, что правильно считать - наверное - вот так, специально выделяю скобками:

(482.37/120)*20 = 80.395 = 80.40

где первое действие - вычисляем единицу БАЗЫ (получаем точно 4.01975) - и потом берем 20 единиц этой базы. и получаем _точно_ 80.395

правда, это не мешает НДС с авансов считать не так, а именно по ставке 18/118 или 20/120.
"искать логику в налоговом законодательстве - бесполезное занятие".

так что тут зависит не столько от математики, скольо от того как догворится о порядке расчета.. ;-)
30. dvk09 2 16.01.19 08:56 Сейчас в теме
Да фигня всё это, у нас торговые сети умудряются вычислить 18% НДС из 19810.00 руб. в размере 3021.90.
Наши спокойно подгоняют документы под эту сумму..
Хотя я сколько ни искал способов вычислить такое значение, так и не смог, всегда получается так: 3021.86

При этом в догоре о порядке расчета с этой сетью указано, что НДС округляем до 2х знаков после запятой.
31. dvk09 2 16.01.19 08:58 Сейчас в теме
Самое интересное, что налоговая спокойно принимает такой НДС.
34. user856012 13 16.01.19 13:41 Сейчас в теме
(31)
Самое интересное, что налоговая спокойно принимает такой НДС.
А почему бы ей его не принять? Он ведь завышен, а не занижен.

А если покупатель такой НДС берет к вычету, так тоже все нормально - ведь продавец уплатил в бюджет именно такую сумму и именно ее он предъявил покупателю - покупатель вправе принять ее к вычету.

P.S. По теме ветки: попробовал воспроизвести описанную ситуацию в 7.7 через Табло - проблема не подтверждается, во всех случаях неокругленный результат равен 80.395, округленный - 80.40. ЧЯДНТ?
32. o.kovalev 114 16.01.19 11:40 Сейчас в теме
Окр(<?>,,)
Синтаксис:
Окр(<Число1>,<Число2>,<Способ>)
Назначение:
Возвращает значение результата округления.
Параметры:
<Число1> - числовое выражение, значение которого надо округлить;
<Число2> - число значащих цифр дробной части или
минус число не значащих младших цифр целой части (не обязателен, по умолчанию - 0);
<Способ> - способ округления граничных значений: 0 - если 1.5 округляется до 1, 1 - если 1.5 округляется до 2 (не обязателен, по умолчанию принимается значение, установленное в окне свойств конфигурации: Конфигурация/Задача/Свойства страница Задача, поле Округление).
33. solutioncp24 136 16.01.19 13:39 Сейчас в теме
Логичнее со скобками считать, а разность 7.7 и 8 объясняется кол-вом знаков после запятой
35. o.kovalev 114 16.01.19 16:57 Сейчас в теме
мне кажется по правилам математики считать слева направо (без скобок) правильнее
36. user856012 13 16.01.19 18:30 Сейчас в теме
(35)
мне кажется по правилам математики считать слева направо (без скобок) правильнее
Креститься надо, когда кажется.

Или уроки той самой математики не прогуливать - тогда не казалось бы.

2 * (2 + 2) - сколько будет?

2 * 2 + 2 - для сравнения?
37. o.kovalev 114 16.01.19 20:23 Сейчас в теме
(36) ну и что вы привели ? в формуле автора темы равнозначные по приоритету действия, смысла в скобках нет, действительно когда они есть набегает погрешность.
38. dakork 33 17.01.19 18:43 Сейчас в теме
Рекомендую глянуть сюда https://infostart.ru/public/693036/ может чем поможет
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот