Б. Страуструп - Язык программирования С++. Специальное издание, 3-изд. Бином. 2004 (1160791), страница 163
Текст из файла (страница 163)
Глава 22. Численные методы 720 Определяя некий скалярный тип в духе встроенных типов, полезно ввести соответствующую специализацию питепс Втйя. Например, если бы я написал тип Диас(для чисел с учетверенной точностью, или если бы поставщик ввел целые числа с расширенной точностью !олй !ой, пользователь был бы в праве ожидать, что для них существуют питепс !1т11я<Яиас1> и питепс !1т11я<!ола !ола>. Можно представить себе специализацию пигпепс 1!пи!я, которая описывала бы свойства типов, определяемых пользователем, мало похожих на числа с плавающей точкой.
В таких случаях для описания свойств типа обычно лучше пользоваться общей техникой, чем специализировать питег1с Йтйя с не входящими в стандарт свойствами. Значения с плавающей точкой представлены как встроенные функции. Однако, целые значения в пи тепе ! ит1я должны быть представлены в такой форме, которая позволила бы использовать их в константных выражениях.
Зто значит, что они должны иметь инициализаторы внутри класса Я ) ОА 6,2). Если вы пользуетесь для этого статическими константными членами, а не перечислениями, не забудьте определить эти статические'члены. 22.2.1. Макросы для предельных значений Для описания свойств целых чисел Сг ь унаследовал из С макросы. Зтп макросы находятся в <с1гтйя> и <11т11я.й>, они имеют имена наподобие СНАЯ ВТТи 1МТ МАХ.
Подобным образом в <с/1оа1> п <Яоа1.й> определены макросы, описывающие свойства чисел с плавающей точкой. Их имена выглядят как ВВЕ М1Л" ЕХР, Л.Т МАТ>1Х п ЕЮВЕ МАХ. Как всегда, макросов лучше стараться избегать. 22.3. Стандартные математические Функции Заголовочные фанлы <сгпа1/г> и <та1й.)г> предоставляют то, что обычно называют <обычными математическими функциями >: с1оиЫе абя (с1оиЫе); // абсолютное значение, в С отсугпсгпвуегп /г' то же, кто /абя1) //абсолютное значение с)оиб)е Табе (дои 6)е), // наииеныиее целое, не иеныиее и' // наибольшее целое, не большее г) г1оиЫе сей 4оиб!е с(); с)оиЫеЯоог (с)оиб)е с(); с)он 61е я ум (с! он Ые и); г1оиЫе рош (г1оиб1е сг, г)оибге е); ,г,гарккосинус' // аркен нус //арктингенс //п1ап(к!у) // гиперболический синус // гиперболический косинус с)оиЫе рота (с1оиЫе с(, ии 1); с!оиЫе соя (с1оиЫе); с1оиб!енп (с1оиб!е); с1ои61е гап (с!ои61е); с1оиб!е асов (г1оиб!е); с1оиЫе анп (с(оиЫе); доиЫе а1ап (с1оиЫе); г1оиЫе п1ап2 (с1оиЫе х, <1ои61е у); агоиб)е япб (агоиЫе); с1оиЫе сояб (дои61е); О квадратний корень ия а, // д должно быть неотрицательная //г! всгпепени е; ошибки, ешш 0==0 и в<=0, // или если а<0 и е не целое // д в степени г'; в С отсутствует О косинус //синус // тангенс 22.4.
Векторная арифметика 729 йоиЫе 1апб (йоиЫе); йоиЫе ехр (йоиЫе); йои61е 1оу (йоиЫе й); йоиб(е/той (йоиЫе й, йоиЫе т); йоиЫе (йехр (йоиЫе г(, т1!) Кроме того, <стай> и <тай.Ь> предоставляют эти функции для аргументов типа /7оа(и 1опдйоиЫе. Там, где результат неоднозначен — как в случае с функцией аяп () — возвращается значение, ближайшее к О. Функция асов () возвращает неотрицательный результат.
Ошибки индицируются установкой еггпо из <сеп по> в состояние ЕО(гМ для ошибок, связанных с выходом из области определения, и в состояние ЕКАгч БŠ— для ошибок выхода за пределы диапазона. Например: оойЩ ( впво=О; О очистка стирого состояния, индгщирующего ошибку вугг (-1); 1/ (егпю == Е1>ОМ) сегг « "зугг б не определена для отрицательных аргументов'; роиг(питег)с Ртаз<йои61е>стах (),2); г/ (еггпо == ЕРА)УВЕ) сегт « "результат рот () слишком велик для типа йоиЫе'; Так уж исторически сложилось, что несколько математических функций находятся не в <стай>, а в заголовочном файле <сзЫ!16>: ин а бе (т1); //абсолютное значение 1опуабв(1опу); //абсолютиоезначение(вСотсутствует) 1опу !а бе (1опу)г // абсолютное значени е з(гис! г(го 1( 1тр1етеп1а1!оп йе/спей уиог, гет, ) з!гис1 Ы(ь 1( (тр!етепсас(о~ йе(гней уио1, гет; ) аао 1й(о (тгп, гпг й); // деление и иа й, возвращает (частное, остаток) Ыго 1(й(о (!а!п, гп! й); // деление п пай, возвращает (частное, остаток) 0 (в С отсутствует) Ыт 11й(о(1опу!пг и,!опут1й); //деление п на й, возвращает (частное, остаток) 22.4.
Векторная арифметика Значительная часть работы с числами связана с относительно простыми одномерными векторами чисел с плавающей точкой. В частности, такие вектора хорошо поддерживаются в архитектурах высокопроизводительных машин, для таких векторов написаны широко распространенные библиотеки, и во многих областях деятельности йоиб!е 1оу!О (г1ои61е гй; йоиЫе той7" (дои 61е аг, йоиЫе' р); йоиб(е/гехр ЫоиЫе й, т!" р); //гиперболическиа тангенс //зкспоиента, основание е //натуральный (с основаниеяг е) логарифм, О й должно бьипь пол ожгвпельиьт // десятичный логарифм, //г1 должно быть потлжнлтльиылг // возвращает дрооную чаапь й, /I целая часть помещается в 'р // находит х в (.5, 1) и у пгакие, что //й=х*рош(2,у), возврагцаегп хи сохраняет у в р // остапгок от делетгя й иа т, того же знака, что й ,1/ й'рот (2, 1) Глава 22.
Численные методы 730 22.4.1. Конструирование ча(аггау Тип иа1аггау и связанные с ним средства представлены в <иа1аггау>ч 1етр!а1е<с1акк Тл с!акк кгс(> иа! агтау ( //пре»сп>веление риЬйс !урсс(е/Тиа1ие 1уре; иа1аггау ((; ехр!>од иа!аггиу (ксее 1 п(; иа1апау (сопя! Тй па!, к!ее ! и(, иа1ипау (сопя1 2 р,к!ее !и(; иа1агтау (сопк1 иа1а>тауй и(; иа(атгау (сопя1 кдсе аггау<Тэй) иа1аггау (сопя! ук1!се аггау<Тэй) иа1аггау (сопк1таки аггау<Т й) ои!аггау (сопя! 1псдгес! аггау<Т й) -иа1ап ау ((; определены в пространстве имен яЫ и //иа!аггоу с ра эл>ерол> я!ге (1 == 0 // п элементов со зничениел> Т!1 // и элел>енпи>в со зниневиел иа! // и элеяентов со зниненияяи р(01 р(!1, ...
//копия о //сл. у 22.4.6 //ся з 22.4.8 // .д22.4.у 0 .дг2.4.!У Этот набор конструкторов позволяет нам инициализировать иа1аггау, используя числовые массивы вспомогательных типов нли отдельные значения. 11апример: придается большое значение агрессивной оптимизации программ, применяющих подобные вектора. Поэтому стандартная библиотека предоставляет вектор — который называется иа1ап ау — разработанный специально ддя ускорения распространенных численных онерапий над векторами, Глядя на свойства вектора иа1аггау следует помнить, что они рассчитаны на сравнительно низкоуровневые быстрые вычисления.
В частности, главным критерием проектирования считалась не легкость применения, а эффективность использования высокопроизводительных компьютеров на основе приемов агрессивной оптимизации. Если ваша главная пель — достижение гибкости и универсальности, а нс эффективности, то, возможно, вам лучше строить вычисления на основе контейнеров из глав 16 и 17, чем стараться втиснуться в рамки простого, эффективного и подчеркнуто традиционного вектора иа!аггау. Кто-нибудь может сказать, что иа1апау следовало бы назвать иес1ог(вектор), поскольку он является традиционным математическигн вектором, а иес1ог Я 16.3) следовало бы назвать аггау (массив), однако терминология развивалась иначе.
иа1аггад— это вектор, оптимизированный для численных расчетов, а вес!от — это гибкий контейнер, разработанный для хранения объектов различного типа и манипулирования с ними, массив же — это низкоуровневый встроенный тип. Тип иа1аггау поддерживается четырьмя вспомогательными типами, служащими для определения подмножеств иа1аггад; ° к1!се аггау и дк1!се атгад представляют понятие срезов (э((се) (Я 22А.6, Я 22А.8); * така оп ау определяет подмножество, по-разному помечая элементы вектора (9 22А.9); ° (пй(гес1 аггау содержит не сами элементы, а нх индексы (Я 22А.10). 731 22.4.
Векторная арифметика //занилгаем,веста; лил лгожелг присвоить // что-нибудь оО позже // 1000 элелгентов со значенггелг)(оа1() ==ООГ иа!аггау<с1оиЫе> иО; иа1аггау<Яоа1> и! (!000(, иа(аггау<!п1> и2 ';1, 2000(; // 2000 элеменггюв со значением -! иа1аггау<г!оиб!е> и8 (100, 9 В064) // ошибкаг разлгер иа!а ггпу задан // числом с пггаггаклигей точкой //о4 илгеет оЗ.з!ев1) элелгенпгов иа1аггау<сгоиб!е> и4=-иВ, В двухаргументных конструкторах значение указывается перед числом элементов. В этом отличие от общепринятой записи для стандартных контейнеров Я 16.3.4).
При копировании размер получающегося иа1аггау определяется числом элементов в аргументе, который должен быть скопирован. Больщинство программ нуждается в данных, введенных или взятых из таблицы, это поддерживается конструктором, который копирует элементы из встроенного массива. Например: сопз1 г!оиб!е и<1(( - ( О, 1, 2, 8, 4 ), сопз1гп1ИЦ =(О, 1, 2,3, 4 (; иа(аггау<с(оиЫе> иВ (ис(, 4(; иа1аггау<доиЫе' и4 (и1, 4(г иа!оп ау<г1оиб!е> иб (ис1, В~г //4 элелгентаг О, 1, 2, 3 // ошибка в гпипег и не являшпся укаэагпелелг нп дание // не определено; в иниг(гголизагпоре слшиком // ты о элементов 22.4.2. Индексация и присваивание для иа!аггау Индексация иа1агтау применяется как для того, чтобы обращаться к отделыгым чле- нам, так и для того чтобы получать подмассивы: 1етр!а1е<с!азз Т> с!азз иа!аггау ( риб!!с: 0- иа!агтауй орега1ог= (сопл! иа!аггауй и); ип!ап а уй орега1ог= (сопз1 Тй иа!) Т орегагог(( (зсее 1г сопз1, Тй орега1ог(),'зове 1), // копирование о // присваива ние иа! каждому элементу Такая форма инициализации очень важна, поскольку есть много численных программ, которые выдают данные в виде больщих (обычных) массивов.