Неточность в расчетах
Компенсация погрешностей при операциях с числами с плавающей запятой
Работа посвящена погрешностям округления, возникающим при вычислениях у чисел с плавающей запятой. Здесь будут кратко рассмотрены следующие темы: «Представление вещественных чисел», «Способы нахождения погрешностей округления у чисел с плавающей запятой» и будет приведен пример компенсации погрешностей округления.
В данной работе примеры приведены на языке програмиирования C.
Представление вещественных чисел
Рассмотрим представление конечного действительного числа в стандарте IEEE 754-2008 в виде выражения, которое характеризуется тремя элеменами: S (0 или 1), мантисса M и порядок E:
v = -1 S * b (E — BIAS) * M
- основанием b (стандартом определено три двоичных формата и два десятичных);
- длиной мантиссы p, определяющей точность представления числа, измеряется в цифрах (двоичных или десятичных);
- максимальным значением порядка emax;
- минимальным значением порядка emin; стандарт требует, чтобы выполнялось условие:
- BIAS (смещение); порядок записывается в т. н. смещенной форме, т. е.
реальное значение показателя степени равно E-BIAS.
Ниже в таблице даны параметры стандартных форматов чисел с плавающей запятой. Здесь: w — ширина битового поля для представления порядка, t — ширина битового поля для представления мантиссы, k — полная ширина битовой строки.
В следующией таблице представлены диапазоны изменения и точность стандартных 32 и 64-х разрядных форматов вещественных чисел с плавающей запятой.
Здесь «Точноть, Эпсилон» — наименьшее число, для которого истинно выражение:
Данная величина «Эпсилон», характеризует относительную точность операций сложения и вычитания: если прибавляемая к x или вычитаемая из x величина меньше, чем epsilon*x, то результат останется равен x. На практике, в ряде случаев, при использовании в аддитивных операциях величин, приближающихся по порядку к epsilon*x, начинают сказываться погрешности округления меньшего слагаемого. О таких ситуациях и пойдет речь в данной работе.
Рассмотрим представление вещественного числа для типа данных float(Binary32).
В данном примере:
Заметим, что при выполнении операций с вещественными числами часто результат не будет помещаться в N-разрядные матиссы, т.е. будет происходить округление. Округление в одной вычислительной операции не превывает порядок EPSILON/2, но когда нам требуется делать много операций, то для повышения точности вычисления результата нам надо научиться находить, насколько именно результат каждой конкретной операции округлён.
Более подробно про округления и нарушение аксиоматики рассказано в файле makarov_float.pdf (ссылка на материал внизу).
Способы нахождения погрешностей округления у чисел с плавающей запятой
Данную проблему исследовали многие специалисты, наиболее известными из них являются: Дэвид Голдберг, Уильям Кэхен, Джонатан Ричард Шевчук.
Ниже мы рассмотрим алгоримы нахождения погрешностей округления, приведенные в работе Шевчука, на примере двух функций:
- TwoSum — функция нахождения погрешности округления при сложении.
- TwoProduct — функция нахождения погрешности округления при умножении.
Для правильного понимания указанных алгоритмов мы будем опираться на теоремы, которые рассмотрены в работе Шевчука. Теоремы приводим без доказательств.
Говоря, что число a является p-битовым числом, имеется ввиду, что длина матиссы числа a представляется p битами.
TwoSum
Теорема: пусть числа a и b являются p-битовыми числами с плавающей запятой, где p >= 3, тогда следуя данному алгоритму мы получим 2 числа: x и y, для которых выполняется условие: a + b = x + y. Причем x является апроксиммацией суммы a и b, а y является погрешностью округления вычисления числа x.
TwoProduct
В действительности, алогритм находжения погрешности огругления при умножении двух вещественных чисел состоит из 2-х функций: Split — вспомогательной функции и функции TwoProduct, где мы находим погрешность.
Рассмотрим алгоритм функции Split.
Split
Теорема: число a — p-битовое число с плавающей запятой, где p >= 3. Выберем точку разрыва s, где p/2 = |a_low| и a = a_hi + a_low.
Теперь перейдем к анализу функции TwoProduct.
TwoProduct
Теорема: пусть числа a и b являются p-битовыми числами с плавающей запятой, где p >= 6. Тогда, выполняя данный алгоритм, мы получим 2 числа: x и y, для которых выполняется условие: a*b = x + y. Причем x является апроксиммацией произведения чисел a и b, а число y является погрешностью округления вычисления числа x.
Видно, что конечный результат представляется парой N-битовых вещественных чисел: результат + погрешность. Причем второе должно иметь порядок не более EPSILON по отношению к первому.
Пример компесации погрешностей округления у чисел с плавающей запятой
Теперь перейдем к практическим расчетам, которые построены на алгоритмах Шевчука. Найдем погрешности округления при сложении и умножении чисел с плавающей запятой и проанализируем, как накапливается погрешность.
Погрешность округления суммы
Приведем пример простейшей программы суммирования:
В результате работы программы, мы должны получить два одинаковых числа: 2,7892 и 2,7892. Но в консоль было выведено: 2,7892 и 0,0078125. Отсюда видно, что погрешность накопилась очень большая.
Теперь попробуем сделать то же самое, но, используя алгоритм Шевчука, будем накапливать погрешность в отдельную переменную, а затем скомпенсируем результат путем прибавления ошибки к главной переменной суммы.
В итоге мы получаем 2 числа: 2,7892 и 0,015625. Результат улучшился, но погрешность все равно дает о себе знать. В данном примере не была учтена погрешость, возникающая в операции сложения, в функции TwoSum():
Будем компенсировать результат на каждой итерации цикла и перезаписывать ошибку в переменную, которая накапливает погрешность округления в операции суммирования. Для этого модифицируем функцию TwoSum(): добавим переменную isNull типа bool которая указывает на то, стоит ли нам накапливать погрешность или же стоит ее перезаписать.
В итоге, result будет представляться 2 переменными: result — главная переменная, error1 — погрешность операции result += val.
Код будет выглядеть следующим образом:
Программа выведет числа: 2,7892 и 2,789195.
Заметим, что здесь не была учтена погрешность округления, возникающая в операции умножения:
Учтем эту погрешность путем добавления функций учета погрешностей умножения, которые разработал Д.Р. Шевчук. При этом переменная val будет представлена двумя переменными:
Таким образом, result будет представляться 3 переменными: result — главная переменная, error1 — погрешность операции result += val, error2 — погрешность операции result += errorMult.
Так же мы будем складывать переменные error1 и error2, а погрешность от этой операции записывать в error2.
В консоль были выведены следующие числа: 2,7892 и 2,789195.
Это говорит о том, что погрешность округления умножения достаточно мала, чтоб проявиться даже на 10 миллиардах итераций. Данный результат является максимально приближенным к исходному числу, если учитывать погрешности в операциях сложения и умножения. Для получение более точного результата можно ввести дополнительные переменные, учитывающие погрешности. Скажем, добавить переменную, учитывающую погрешность в операции накопления основной погрешности в функции TwoSum(). Тогда эта погрешность будет иметь порядок EPSILON 2 , по отношению к главному результату (первая погрешность будет иметь порядок EPSILON).
Погрешность округления умножения
Посчитаем число 1.0012 101 в цикле, т.е. сделаем следующие:
Заметим, что точный результат, с точностью до пятнадцатого знака после запятой, равен 1.128768638496750. Мы получим: 1.12876391410828. Как видно, погрешность оказалось достаточно большой.
Выведем переменную val, приведя ее к типу данных double, и посмотрим, что в нее на самом деле записалось:
Мы получим число 1.00119996070862. Это говорит о том, что в программировании даже самая точная константа не является ни надежной, ни константой. Поэтому, наш реальный точный результат будет равен 1.128764164435784, с точностью до пятнадцатого знака после запятой.
Теперь попробуем улучшить полученный ранее результат. Для этого введем компенсацию результата вычислений, путем учета погрешности округления в операции умножения. Так же будем пытаться прибавлять накопившуюся погрешность к переменной result на каждом шаге.
Программа выводит следующее число: 1.12876415252686. Мы получили погрешность 1.0e-008, что меньше чем EPSILON/2 для типа данных float. Таким образом, данный результат можно считать достаточно хорошим.
Итоги
1) В данной работе было рассмотрено представление чисел с плавающей запятой в формате стандарта IEEE 754-2008.
2) Был показан способ нахождения погрешностей округления в операциях сложения и умножения у чисел с плавающей запятой.
3) Были рассмотрены простые примеры компенсации погрешностей округления у чисел с плавающей запятой.
Работу выполнил Виктор Фадеев.
Консультировал Макаров А.В.
Расчет заработной платы: какие ошибки допускают работодатели
background:white»> В расчете заработной платы одна неточность часто влечет за собой череду ошибок. Чтобы их избежать, нужно начать с правильного понимания самого термина «зарплата».
Какие распространенные ошибки совершают работодатели в процессе расчета заработной платы? Как их предотвратить, где искать подсказки?
1. Неверное определение состава заработной платы.
Четкое определение понятию «зарплата» дается в ст.129 ТК РФ. Заработная плата (оплата труда работника) включает:
- вознаграждение за труд, которое зависит от ряда факторов: квалификации работника, сложности, количества, качества и условий выполняемой работы;
- компенсационные выплаты: доплаты и надбавки компенсационного характера, в том числе за работу в условиях, отклоняющихся от нормальных, работу в особых климатических условиях и на территориях, подвергшихся радиоактивному загрязнению, и иные выплаты компенсационного характера;
- стимулирующие выплаты: доплаты и надбавки стимулирующего характера, премии и иные поощрительные выплаты.
Из определения следует, что зарплата состоит из трех частей: основной части (оклад работника), компенсационной и стимулирующей части.
Почему важно понимать, что входит в определение «зарплата»? Потому что от этого понимания зависит, какие выплаты нужно включать в расчет среднего заработка. Если этого понимания нет, высок риск совершить вторую ошибку.
2. Неверное определение состава выплат, включаемых в расчет среднего заработка, в том числе премий.
Расчет среднего заработка регламентирован Постановлением Правительства РФ от 24.12.2007 № 922 . В п. 2 данного Постановления говорится, что в расчет среднего заработка включаются все виды выплат, предусмотренные системой оплаты труда .
Выплаты, которые включаются в расчет среднего заработка:
- зарплата, начисленная по тарифным ставкам, окладам (должностным окладам) за отработанное время; начисленная за выполненную работу по сдельным расценкам; начисленная за выполненную работу в процентах от выручки от реализации продукции (выполнения работ, оказания услуг), или комиссионное вознаграждение; выданная в неденежной форме;
- денежное вознаграждение, начисленное за отработанное время лицам, замещающим государственные должности РФ, государственные должности субъектов РФ, депутатам, членам выборных органов местного самоуправления, выборным должностным лицам местного самоуправления, членам избирательных комиссий, действующих на постоянной основе;
- денежное содержание, начисленное муниципальным служащим за отработанное время;
- начисленные в редакциях СМИ и организациях искусства гонорар работников, состоящих в списочном составе этих редакций и организаций, и (или) оплата их труда, осуществляемая по ставкам (расценкам) авторского (постановочного) вознаграждения;
- зарплата, начисленная преподавателям профессиональных образовательных организаций за часы преподавательской работы сверх установленной и (или) уменьшенной годовой учебной нагрузки за текущий учебный год, независимо от времени начисления;
- зарплата, окончательно рассчитанная по завершении предшествующего событию календарного года, обусловленная системой оплаты труда, независимо от времени начисления;
- надбавки и доплаты к тарифным ставкам, окладам (должностным окладам) за профессиональное мастерство, классность, выслугу лет (стаж работы), знание иностранного языка, работу со сведениями, составляющими государственную тайну, совмещение профессий (должностей), расширение зон обслуживания, увеличение объема выполняемых работ, руководство бригадой и другие;
- выплаты, связанные с условиями труда, в том числе выплаты, обусловленные районным регулированием оплаты труда (в виде коэффициентов и процентных надбавок к заработной плате), повышенная оплата труда на тяжелых работах, работах с вредными, опасными и иными особыми условиями труда, за работу в ночное время, оплата работы в выходные и нерабочие праздничные дни, оплата сверхурочной работы;
- вознаграждение за выполнение функций классного руководителя педагогическим работникам государственных и муниципальных образовательных организаций;
- премии и вознаграждения, предусмотренные системой оплаты труда;
- другие виды выплат по заработной плате, применяемые у работодателя.
Постановление Правительства РФ от 24.12.2007 № 922 регламентирует расчет отпускных и компенсаций за неиспользованный отпуск и иных случаев, то есть социальные пособия (пособие по временной нетрудоспособности и детские пособия) не берутся.
Нужно иметь в виду, что компенсация и компенсационные выплаты — разные понятия. Компенсация — это не зарплата, не выплата за труд. Следовательно, включать ее в средний заработок не нужно.
Что касается стимулирующих выплат, то они бывают разные. Одно дело, когда, например, у работника в трудовом договоре зафиксировано, что ему назначен оклад и 10 % премии ежемесячно от оклада. И в данном случае эта премия будет за труд.
Другое дело, когда премия выплачивается, например, к какому-то профессиональному празднику, и это предусмотрено локальными нормативными актами, но не является выплатой за труд. Соответственно, включение такой премии в расчет среднего заработка необоснованно. Чтобы не запутаться и не сделать ошибку, необходимо понимать сущность стимулирующей выплаты.
Все выплаты, которые включаются в расчет среднего заработка, должны быть предусмотрены локальными нормативными актами, зафиксированы в трудовом договоре. Просто так включить какую-то выплату нельзя. Согласно ст. 57 ТК РФ , в трудовой договор должны быть обязательно включены условия оплаты труда, в том числе размер тарифной ставки или оклада (должностного оклада) работника, доплаты, надбавки и поощрительные выплаты .
3. Неверное определение расчетного периода при определении среднего заработка.
О расчетном периоде при определении среднего заработка говорится в п. 5 Постановления Правительства РФ от 24.12.2007 № 922.
При исчислении среднего заработка из расчетного периода исключается время, а также начисленные за это время суммы, если:
- за работником сохранялся средний заработок, за исключением перерывов для кормления ребенка;
- работник получал пособие по временной нетрудоспособности или пособие по беременности и родам;
- работник не работал в связи с простоем по вине работодателя или по причинам, не зависящим от работодателя и работника;
- работник не участвовал в забастовке, но в связи с этой забастовкой не имел возможности выполнять свою работу;
- работнику предоставлялись дополнительные оплачиваемые выходные дни для ухода за детьми-инвалидами и инвалидами с детства;
- работник в других случаях освобождался от работы с полным или частичным сохранением заработной платы или без оплаты.
При расчете среднего заработка, когда мы начисляем зарплату, основным документом, в котором можно видеть, где был работник — в отпуске, на больничном и т д., является табель учета рабочего времени.
Учитывайте сотрудников, рассчитывайте зарплаты, больничные, отпускные, налоги и взносы.
Если в расчетном периоде при исчислении среднего заработка, например, когда работник находится в командировке, есть неявки по невыясненным причинам, этот период мы исключать из расчета не можем. Также мы не можем исключать прогулы. В п. 5 Постановления ничего про них не сказано.
Мы не можем исключать перерывы для кормления ребенка, хотя за этот период выплачивается средний заработок.
Советы работодателям
- Четко разграничивайте зарплату и средний заработок.
- Смотрите, что зафиксировано в локальных нормативных актах. Выплаты должны быть четко прописаны во внутренних документах организации.
- Правильно и четко заполняйте табель учета рабочего времени. Если работник в командировке, ставьте код «К». Если стоит код «К», а вы выплачиваете зарплату, то это необоснованно. Все начисления делайте только на основании табеля учета рабочего времени. Он должен заполняться в каждом обособленном подразделении.
Начисление зарплаты: новое в 2020 году
Первое нововведение, которое повлияет на расчет зарплаты в 2020 году, — это увеличение МРОТ. Приказ Минтруда РФ от 09.08.2019 N 561н утвердил величину прожиточного минимума для трудоспособного населения за II квартал 2019 года в размере 12 130 руб. Это значит, что с 2020 года минимальный размер оплаты труда тоже будет составлять 12 130 руб. Известно, что Госдума поддержала принятие в первом чтении поправки в Федеральный закон «О минимальном размере оплаты труда».
Для работодателей эта новость важна прежде всего потому, что ст. 133 ТК РФ обязывает устанавливать зарплату не ниже МРОТ. Однако субъекты РФ, с учетом социально-экономических условий и величины прожиточного минимума трудоспособного населения, вправе соглашением о минимальной заработной плате устанавливать свой размер минимальной заработной платы.
Не стоит также забывать о требовании ст. 134 ТК РФ индексировать зарплату в связи с ростом цен на товары и услуги. Об этом мы подробнее писали в статье «Индексация заработной платы: право или обязанность работодателя?».
Страховые взносы
Что касается страховых взносов, то ставки в 2020 году останутся на прежнем уровне:
Постановлением Правительства РФ от 06.11.2019 № 1407 установлена предельная величина базы для исчисления страховых взносов на 2020 год:
- для взносов на ОПС — 1 292 000 руб.;
- для взносов на ОСС (на случай временной нетрудоспособности и в связи с материнством) – 912 000 руб.
Если выплаты по заработной плате вышли за лимит в 912 000 руб., то взносы на ОСС платить не нужно, а если выплаты превысили 1 292 000 руб., то на ОПС будет применяться тариф 10 %.
Ставки страховых взносов на травматизм составят от 0,2 % до 8,5 % и будут зависеть от ОКВЭД компании.
Выплачивая зарплату, компании и предприниматели становятся налоговыми агентами по отношению к сотрудникам. Поэтому они должны начислить НДФЛ на сумму зарплаты, удержать его из доходов сотрудника и перечислить в бюджет. Налог также начисляется на отпускные и на пособия по больничным листам. А вот декретные пособия от НДФЛ освобождены.
Ставка налога на доходы физлиц составляет 13 %. При этом важно помнить о том, что величина удержанного НДФЛ не должна превышать 50 % от суммы выплаты сотруднику.
Стоит отметить, что с 2020 года срок для представления сведений о доходах физических лиц по форме 2-НДФЛ и годового расчета по форме 6-НДФЛ будет сокращен на месяц — до 1 марта. Предельный срок для представления отчетности по НДФЛ будет, таким образом, унифицирован.
Вести учет НДФЛ, формировать и сдавать 6‑НДФЛ и 2‑НДФЛ через удобный веб-сервис.
Но поскольку в 2020 году 1 марта выпадает на выходной, 2-НДФЛ и 6-НДФЛ можно представить не позднее 2 марта 2020 года (Письмо ФНС РФ от 15.11.2019 № БС-4-11/23242@).
По НДФЛ есть также и другие изменения на 2020 год. Например, новые контрольные соотношения для отчетов по НДФЛ, уплата НДФЛ за счет средств налогового агента в некоторых случаях и др. Подробнее о них читайте в статье «НДФЛ — 2020: основные изменения».