1626435587-51311eae4652e8ad616b5bdef025cbb3 (844239), страница 8
Текст из файла (страница 8)
(Функции с аналогичными именами впространстве имен std:: определены в заголовочном файле <cmath>.)Заметим также, что в отличие от чисел с плавающей точкой, языкСи не представляет средств для отслеживания переполнения целочисленных переменных. В случае возникновения переполнения устанавливается соответствующий флаг состояния процессора, который, однако,нельзя проверить средствами Си. Для его проверки можно использовать, например, команду условного перехода jo языка Ассемблер:inline bool mult(int a,{*pc = a*b;_asm { //синтаксисjo ON_FAIL}return true;ON_FAIL: return false;}int b, int *pc)Microsoft Visual C//в случае успешного выполнения//в случае переполнения *pcАльтернативным решением может быть использование значительноменее лаконичных (но при этом обладающих большей переносимостью)проверок средствами языка Си.2.4.
Точность вычисленийВвиду конечности количества машинных чисел, вычисления с плавающей точкой на ЭВМ являются приближёнными. В этом несложно убедиться, выполнив в gnuplot команду print 0.1+0.2-0.3, либопроизведя те же вычисления в программе на языке Си. Результат(5,55 · 10−17 ) близок к нулю, но тем не менее нулю не равен. Каковаточность вычислений на компьютере?Погрешность результата арифметических операций наподобие рассмотренного выше примера связана с округлением чисел. Так, точ13ная запись каждого из слагаемых 0,1 = 10, 0,2 = 15 и 0,3 = 10вдвоичном виде содержит бесконечное количество разрядов, поскольку разложение на простые множители знаменателя каждой из указанных обыкновенных дробей содержит 5.
При вводе в компьютер эти35числа округляются до = 52 двоичных разрядов, в результате чеговозникает относительная погрешность 2−(+1) . Результат произвольной арифметической операции также может содержать относительнуюпогрешность округления 2−(+1) = /2. Число называют18 , единицей в младшем разряде мантиссы. Другими, илисловами, число — это минимальная степень двойки (или, в общем случае, основания системы счисления), при сложении которой с единицейрезультат будет отличен от единицы. Для чисел с одинарной точностью(float) 1 = 2−23 ≈ 1,2 · 10−7 , для чисел с двойной точностью (double)2 = 2−52 ≈ 2,2 · 10−16 .Подчеркнём, что характеризует именно относительную погрешность; абсолютная величина ошибки равна произведению 21 · 2 , где — двоичный порядок вычисляемой величины.
Указанная относительная ошибка округления (/2) относится к операциям умножения и деления, а также возникает при вводе числовых констант (наподобие 0,1,0,2 и 0,3 в примере выше). Самой «опасной» операцией с точки зренияошибки является вычитание чисел одного порядка величины и одногознака (или, что то же самое, сложение почти противоположных чисел).Рассмотрим подробнее приводящий к ошибкам вычислений процессокругления — отбрасывание разряда за пределами точности вычисления. Для простоты рассмотрим примеры округления десятичных чиселдо целых: ≈ 3, ≈ 3.
В какую сторону следует округлять 2,5? Согласно общеизвестному арифметическому правилу, 5 следует округлять вбо́льшую сторону, так что 2,5 ≈ 3. Какую ошибку мы совершим в среднем при округлении большого количества чисел в процессе вычислений? Полагая возникновение каждой из десяти цифр в отбрасываемомразряде равновероятным, несложно вычислить математическое ожидание ошибки, к которой приведёт такой способ в случае произвольногоколичества разрядов мантиссы:эпсилонмашиннымULP⟨⟩ =)︀ ′′ (︀· 0−1−2−3−4+5+4+3+2+1 = ,102(3)где ′ — единица в первом разряде мантиссы за пределами точностивычислений (в двоичной системе ′ = /2).В случае двоичной арифметики существование проблемы накопления ошибки округления, или, ещё более очевидно ввиду наличиявсего одной отличной от нуля цифры.
При округлении бит 12 аналогичен цифре 510 , равняясь половине от основания системы счисления.Если округлять 12 всегда в бо́льшую сторону подобно тому, как мыдрейфа18Сокращение от англ. unit in the last place или unit of least precision.36привыкли поступать с 510 , ошибка округления будет всегда неотрицательна.Легко заметить, что ответ (3) для ⟨⟩ будет одинаковым в любойсистеме счисления с чётным основанием, в том числе и в двоичной.Отличие от нуля математического ожидания ошибки округления ⟨⟩означает, в частности, что в сумме из слагаемых либо в результатебольшого числа арифметических операций погрешность будет возрастать приблизительно пропорционально : ≈ ⟨⟩ = · ′ /2.Отличие от нуля ⟨⟩ и постоянство знака ошибки хорошо заметно вфинансовых расчётах.
Поскольку доли копеек (центов, пенсов и т. п.)неизбежно округляются до целых, бухгалтерские отчёты имеют тенденцию расходиться, а организовав определённым образом (в строгомсоответствии с арифметическим правилом!) процесс округления в банке, можно легко получить источник нетрудовых доходов. Для решенияданной проблемы был придуман способ округления, обычно называемый «банковским» или «финансовым». В соответствии с ним, округление средней цифры (510 , 12 и т. п.) производится в сторону чётногопредыдущего разряда. Т.
е. 2,5 ≈ 2, 3,5 ≈ 4 и т. д. Заметим, что количество чётных и нечётных разрядов одинаково в системах с чётнымоснованием, а только в таких системах и возникает проблема с округлением средней цифры. Следовательно, для «банковского»округления√имеем ⟨⟩ = 0, что даёт рост погрешности ( ) вместо ( ).Очевидно, можно решить проблему с ⟨⟩ ≠ 0 и другими способами.Например, можно выбирать направление округления 510 (12 ) случайным образом, или чередовать направления. Каждый из указанных способов не лишён недостатков: при случайном выборе направления расчёты теряют воспроизводимость (их результат становится случайнойвеличиной); использование чётности операции подразумевает хранениеномера операции и передачу его вместе с операндами и т.
п. «Банковское» округление свободно от указанных недостатков, однако в случаеналичия корреляций в отбрасываемом разряде оно также может приводить к отличию от нуля математического ожидания ошибки.В соответствии со стандартом IEEE 754, по умолчанию используется «банковское» округление, однако предусмотрены ещё четыре способа: арифметическое округление, в сторону +∞, в сторону −∞ и в сторону нуля (отбрасывание дробной части).
Используемый ЭВМ способокругления может быть изменён установкой соответствующего флагасопроцессора.372.5. ЗаключениеПовседневный опыт подсказывает нам, что калькуляторы (и темболее компьютеры) выполняют арифметические операции чрезвычайно быстро и никогда не ошибаются. Многие склонны переносить этотвывод с бытовых вычислений на научные расчёты. Последние, однако,таят в себе немало особенностей и готовы предложить начинающемувычислителю множество сюрпризов и неожиданных проблем.
Именнопоэтому каждому исследователю, использующему в своей работе численные методы решения задач, полезно иметь представления об изложенных выше основах компьютерной арифметики.Перечислим в порядке убывания очевидности несколько типичныхпримеров, демонстрирующих важность анализа ошибок и знания основных принципов компьютерной арифметики. Ещё ряд примеров приведён в конце главы в качестве упражнений для самостоятельного изучения.1. Научные расчёты зачастую могут включать огромное количество операций, несоизмеримое с повседневным опытом: на решение одной задачи может требоваться несколько дней работы современногомногопроцессорного компьютера, вычислительная мощность которогоизмеряется в терафлопсах19 .
При этом малые ошибки округления, допускаемые при выполнении каждой арифметической операции, могутнакапливаться и приводить к полному искажению результата.2. Решение некоторых задач (их принято называть) может приводить к существенному увеличению погрешности входных данных даже при относительно небольшом количествеопераций. Примером может служить поиск точки пересечения почтипараллельных прямых, вычисление корней многочлена высокой степени, нахождение собственных чисел несимметричной матрицы большогоразмера и др.3. Наличие погрешности округления приводит к нарушению ассоциативности арифметических операций: например, −1 + (1 + 2 ) ̸≠= (−1 + 1) + 2 .
Как следствие, при вычислении разности близких помодулю величин необходимо оптимизировать порядок выполнения операций для уменьшения погрешности результата. В некоторых случаяхперед вычислением выражения необходимо выполнить тождественныепреобразования либо разложение в ряд, в противном случае результат может не содержать ни одного верного знака (см. упражнение 7 наплохо обуслов-ленными19 Терафлопс (от англ. аббревиатуры Flops, floating-point operations per second) —единица измерения быстродействия ЭВМ, равная 1012 операций с плавающей точкой в секунду.38√√с. 68). Например, для вычисления разности1 + 2 − 1 − 2 при ≪ 1√√выгодно переписать её в виде 2 2 /( 1 + 2 + 1 − 2 ), что позволит избежать вычитания близких величин. Аналогичный приём необходимдля предотвращения потери точности при вычислении близкого к нулю корня квадратного уравнения[A7, с.
11]: при 2 ≫ числитель√2стандартной формулы (− ± − )/ содержит разность близкихвеличин. Порядок сомножителей в произведении, хотя и не влияет наответа, также может быть очень важен. Неправильный выбор порядка сомножителей способен привести к переполнению разрядной сетки или, наоборот, появлению в расчётах машинного нуля.4.
Зачастую совершенно неожиданное для начинающих физиковвычислителей поведение программ связано со сравнением чисел с плавающей точкой и ветвлением алгоритмов. Так, если имеются две равных величины = , из-за наличия случайных погрешностей при ихвычислении проверка условия if (a < b) может давать как логическую истину, так и ложь. Сравнение двух чисел с плавающей точкойна строгое равенство if (a == b) в большинстве случаев полностьюлишено смысла — вместо этого необходимо сравнивать числа с плавающей точкой приближённо, с заданной абсолютной и относительнойточностью, с которой известны данные значения. Часто встречающаяся ошибка связана с разбиением отрезка (например, области интегрирования) и перебором узлов сетки. Кажущийся на первый взглядочевидным программный код для перебора узлов равномерной сеткиот до точностьfor(double x = a;x <= b;x += (b-a)/N) { ... }очень часто приводит к неверному результату, поскольку в качествеусловия выполнения тела цикла используется сравнение двух чисел сплавающей точкой и .
Чтобы избежать подобной ошибки, рекомендуем вести перебор узлов сетки в цикле с целочисленным индексом:double x, h = (b-a)/N;for(int i = 0; i <= N;++i, x = a + i*h) { ... }В заключение ещё раз подчеркнём, что оценка погрешностей вычислений является нетривиальной задачей, дающей зачастую весьманеожиданные результаты. Ошибки округления являются лишь однимиз источников погрешностей получаемого численного решения. Крометого, свой вклад неизбежно дают приближения, допущенные при формулировке математической модели физической задачи. Сюда можетбыть отнесено также задание приближённых численных параметровмоделируемой физической системы и погрешности численного метода,39обусловленные заменой непрерывных величин дискретными (ошибкидискретизации), сведением математической задачи к конечномерномуприближению, остановом сходящегося к решению бесконечного итерационного процесса после конечного числа шагов и т.