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

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 1474 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 1474 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 32 17.01.19 18:43 Сейчас в теме
Рекомендую глянуть сюда https://infostart.ru/public/693036/ может чем поможет
Оставьте свое сообщение
Вакансии
1С аналитик
Москва
зарплата от 210 000 руб.
Полный день

Руководитель направления 1С
Москва
зарплата от 350 000 руб.
Полный день

1С Программист
Москва
зарплата от 180 000 руб.
Полный день

Программист 1С
Москва
зарплата от 180 000 руб. до 220 000 руб.
Полный день

Аналитик 1С / Бизнес-аналитик
Нижний Новгород
зарплата от 100 000 руб. до 250 000 руб.
Временный (на проект)