книги / Mathematica 5. ╨б╨░╨╝╨╛╤Г╤З╨╕╤В╨╡╨╗╤М
.pdfТаким образом, функция chop заменяет маленькие вещественные числа нулем. Впрочем, иногда вещественное число нужно заменить не нулем, а его приближением к целому или рациональному числу. Для этого предназначены функции, позволяющие вычислить целую и дробную части числа, а также его рациональные приближения.
Целая и дробная части вещественного числа
Всякое вещественное число представляет собой сумму его целой и дробной частей:
•*=[*]+{*) •
Целая часть вещественного числа: функции Floor и IntegerPart
Есть множество способов преобразования вещественных чисел в целые. Но важ нейшими из них являются округление к целому числу и отбрасывание дробной части.
Округление к ближайшему целому, не превосходящему х: функция Floor[x]
Функция Floor [х] представляет собой наибольшее целое, не превосходящее х.
{Floor[Pi] , F lo o r[ - P i], F lo o r[0], F lo o r[2 .99], F lo o r[-2.0001]} { 3 ,-4 ,0 ,2 ,-3 }
Именно функция Floor в математике и называется целой частью числа и обычно обозначается через [х]. Заметьте, что эта функция отсекает дробную часть только не отрицательных чисел. Для отрицательных нецелых чисел ее работа иллюстрируется следующим примером.
F loor[-8.12345678] -9
Поэтому если необходимо просто отбросить дробную часть, лучше воспользоваться функцией In teg erP art.
Отбрасывание дробной части: функция IntegerPart
Функция In te g e rP art просто отбрасывает дробную часть.
{In teg erP art [2 .4 ], In te g e rP art [2.6] , In te g e rP art [-2 .4 ], In te g e rP a rt[ - 2 .6 ] ,In te g e rP a rt[P iA2] }
{2 ,2 ,-2 ,-2 ,9 }
“Потолок” вещественного числа — округление к наименьшему целому, не превосходящему х: функция Ceiling
Выражение C eiling [х] представляет собой наименьшее целое, которое не меньше х.
{C eiling[Pi] , C e ilin g [ - P i], C e ilin g [0], C e ilin g [2.99], C eilin g [-2.0001]}
{4 ,-3 ,0 ,3 ,-2 }
Округление вещественного числа: функция Round
Функции Floor и C eiling позволяют округлить вещественное число к меныиему или большему целому. Иногда же нужно выполнить округление к ближайшему целому. Именно для этого и предназначена функция Round.
Числа, их представление и операции над ними |
63 |
{Round[2.4],Round[2.6],Round[-2.4],Round[-2.6],Round[PiA2]}
{2,3,-2,-3,10}
Однако числа, дробная часть которых равна, .5, имеют два ближайших целых. Та кие числа функция Round округляет к ближайшему четному целому.
Round[Range[20]-10.5]
{-10,-8,-8,-6,-6,-4,-4,-2,-2,0,0,2,2,4,4,6,6,8,8,10}
Дробная часть вещественного числа: функция FractionalPart
Пусть х — вещественное число. Тогда его дробную часть {*} можно определить ра венством: {*} = х - [х]. По этому, общепринятому в математике определению дробная часть всегда неотрицательна и меньше единицы: 0<{х}<1. Однако в системе Mathematica используется несколько иное определение:
FractionalPart[х] = х IntegerPart[х].
Поэтому FractionalPart [х] отрицательна для нецелых отрицательных х.
Чтобы освоиться с функцией FractionalPart, напишем программу, которая рас печатывает результат применения функции FractionalPart к каждому элементу списка. Прежде всего нам понадобится определить функцию, которая оформляет вы вод следующим образом.
FractionalPart[ х ]= результ ат пр и м ен ен и я ф ункции F r a c t i o n a l P a r t к х
Вот как для этого можно определить функцию f .
f=(Print["FractionalPart[",#1,"]=", FractionalPart[#1]] &)
Теперь можем написать программу, в которой функция f применяется к каждому элементу списка.
f/@{x, 2 . 4,0 . 3 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 ' , 2 . 6 , 0 . 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 ' , - 2 . 4,
- 0 . 3 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 ' , - 2 . б , P i , 10, - P i A2, 2 * S i n [ 1 ] , Exp[ P i * S q r t [ 1 6 3 ] ] }
Вот результат
FractionalPart[ x ]= FractionalPart[x]
FractionalPart[ 2.4 ]= 0.4
FractionalPart[ 0.4 ]= 0.4
FractionalPart[ 2.6 ]= 0.6
FractionalPart[ 0.6 ]= 0.6
FractionalPart[ -2.4 ]= -0.4
FractionalPart[ -0.4 ]= -0.4
FractionalPart[ - 2. 6 ]= -0.6
FractionalPart[ n ]= -3+Л
FractionalPart[ 10 ]= 0
FractionalPart [ -7Г ]= 9- 7Г2
FractionalPart[ 2 Sin[l] ]= -1+2 Sin[l]
FractionalPart [ e ^ ]= -262537412640768743+е'Л“” {Null,Null,Null,Null,Null,Null,Null,Null,Null,Null,Null,Null,Null}
Давайте теперь вычислим -262537412640768743+е'Л“,г
-262537412640768743.+Ехр[ Pi*Sqrt(163]]
0.
64 |
Гпава 3 |
Неужели число - 2 6 2 5 3 7 4 1 2 6 4 0 7 6 8 7 4 3 + * ^ * равно нулю? Ведь это означает, что
^Дбзтг __ целое д авайте повторим вычисления.
N[-262537412640768743+Ехр[ Pi*Sqrt[163]]]
- 4 8 0 .
О, это уже какая-то загадка. Разные результаты при вычислении одного и того же выражения! А вот и разгадка: мы проводили вычисления с разной разрядностью, при том в обоих случаях точность была недостаточна. Давайте повторим вычисления с большей разрядностью.
N[-262537412640768743+Ехр[ Pi*Sqrt[163]] ,100]
0 . 9 9 9 9 9 9 9 9 9 9 9 9 2 5 0 0 7 2 5 9 7 1 9 8 1 8 5 6 8 8 8 7 9 3 5 3 8 5 6 3 3 7 3 3 6 9 9 0 8 6 2 7 0 7 5 3 7 4 1 0 3 7 8 2 1 0 6 4 7 9 1 0 1 1 8 6 0 7 3 1 2 9 5 1 1 8 1 3 4 6 1 8 6 1
Теперь мы видим, что - 2 6 2 5 3 7 4 1 2 6 4 0 7 6 8 7 4 3 + * ^ * действительно очень близко к
целому числу 1, от него он о отличается м енее, чем на 8x10 13! М ежду прочим, |
когда |
системы компьютерной алгебры не были столь доступны, как сейчас, число |
дос |
тавляло немало хлопот не только студентам, но и многим вполне серьезным “дядям и тетям”, недостаточно знакомым с признаками трансцендентности чисел. Некоторые
шутники с вполне серьезным видом заявляли, что все говорит о том, что число е является целым, но никто этого пока не доказал, и что за доказательство обещана кругленькая сумма и т.д. А ведь чтобы прямым вычислением установить ложность этого высказывания, необходимо было провести вычисления более чем с 30 десятич ными знаками! Даже вычислить его целую часть на машинах серии IBM/360 или БЭСМ-6 без ухищрений было невозможно! Конечно, на зарубежных машинах были доступны системы компьютерной алгебры, например MACSYMA на IBM/360. Однако на территории СССР доступ к таким системам имели весьма немногие. Кроме того, в советской системе образования следствием застойных явлений были ориентация на идеологические дисциплины (история КПСС, разнообразный марксизм и т.д.), от сутствие свободно выбираемых (студентом, а не деканатом!) курсов и сохранение подчиненной роли курса алгебры (всего три семестра) на уровне прошлого века. В советских университетах даже для студентов-математиков программой не было пре дусмотрено знакомство с современной алгеброй. О компьютерной алгебре не слыша ли и многие преподаватели. Поэтому на территории СССР вера в необходимость пря мого вычисления с довольно большим количеством значащих цифр была не простым заблуждением обывателя, а подкреплялась советской системой образования. Поэтому именно те, кто был заинтересован в финансировании произвольноразрядной арифме тики, и устраивали такие розыгрыши, предварительно тщательно выискивая потенциа льных жертв. Фактически из отечественных машин для проверки гипотезы подходили только машины серии МИР. Но машина МИР-1, во входном языке (Алмир) которой была реализована произвольноразрядная арифметика, имела память объемом всего лишь 4 Кбайт, а машина МИР-2 — 8 Кбайт, причем быстродействие машины МИР-2 из-за частой сборки мусора падало подчас до 200 операций в секунду! Тем не менее благодаря встроенному языку Аналитик, в котором была реализована произвольнораз рядная арифметика и элементы компьютерной алгебры, она справлялась с задачами, одна лишь постановка которых на БЭСМ-6 была весьма трудоемка, и потому очередь к этой машине стояла в десятки раз больше, чем за колбасой. А поскольку заранее никто не мог сказать, сколько времени потребуется на вычисление, спланировать его не представлялось возможным. Что же касается машины МИР-3 (особенно модели МИР-32), то фактически она была доступна только разработчикам, из числа которых
Числа, их представление и операции над ними |
65 |
и находились самые злостные шутники7! Кстати, в те годы системы компьютерной алгебры часто не могли определить, является ли заданное число алгебраическим. На чиная с версии 4 в системе Mathematica не составляет труда записать (и вычислить!) нужный предикат.
Exp [ Pi*Sqrt [163] ]eAlgebraics
False
Всякая история имеет мораль, и эта не исключение: вычисляя дробную часть, не забывайте указывать нужную разрядность и, кроме того, не упускайте из виду цель, ради которой вы проводите вычисления, — подумайте, нельзя ли достичь цели более простым способом. (Мы бы, например, могли сразу спросить систему Mathematica,
является ли алгебраическим числом.) Не забывайте также о том, что подчас с помощью систем компьютерной алгебры удается разрешить вопрос, который остается открытым в течение длительного времени. Впрочем, иногда достаточно вспомнить всего лишь несколько теорем.
Упражнение 3.1. Вычислите не менее к десятичных цифр числа п, начиная с л-й после десятичной точки. Можете ли вы провести вычисления, например, для п = 100 000, к = 1000? Иными словами, можете ли вы вычислить сто первую тысячу (после запятой) знаков в представлении этого числа десятичной дробью?
Решение. Вот самое простое решение, которое обычно приходит в голову неиску шенному читателю. Сначала нужно вычислить к с разрядностью, которая гарантирует п + k + 1 верную цифру, например п + к + 10, а затем в полученной дроби выбрать нужные десятичные знаки. Что касается вычисления п с разрядностью хотя бы 101001. то оно для системы Mathematica никакого труда не представляет. Но вот что касается отсчитать сто тысяч знаков после запятой... Впрочем, в системе Mathematica и для этого предусмотрены нужные функции! Но если немного поразмыслить, то окажется, что решить поставленную задачу можно с помощью функции FractionalPart. “Ну. я об этом сразу догадался!” — высокомерно воскликнет искушенный читатель. Дейст вительно, чего же можно было еще ожидать, если этот раздел посвящен функции FractionalPart? Ну разве что каких-либо трудностей при составлении программы. Но ее составить как раз совсем нетрудно.
n=100000; k=1000; m= N [FractionalPart[10Л (n—1)*Pi],к+10]
Правда, ее нужно предварительно проверить. Это совсем просто, достаточно уменьшить значения п и к , затем провести вычисления
1 Я к их числу никогда не принадлежал. Но когда перед началом вполне серьезного семина ра со мной (тогда еще совсем недавним выпускником университета) и другими участниками се минара попытались сыграть эту незапланированную в программе шутку, я по внешнему виду этого числа определил, что оно не алгебраическое. Отсюда немедленно следовало, что оно не целое. Поэтому шутка теряла смысл (заставить проводит^» вычисления с все большей разрядно стью). Сначала шутники немного смутились, но все же пытались утверждать, что мое мнение совершенно не обоснованно. Тогда мне пришлось вкратце излагать теорию алгебраических чи сел, и примерно к тому моменту, когда я начал упоминать теоремы Гельфонда, легкое см ущ е ние у некоторых шутников начало плавно переходить в глубокий шок. Семинар, начавшийся с
такого незапланированного сообщения о числе е^ * , дальше не продолжался. Дня через два мне доверительно сообщили о благородном предназначении шутки (стимулирование интереса широких кругов научных работников к вычислениям с повышенной разрядностью и , как след ствие, создание мнения о необходимости дополнительного финансирования научных исследо ваний в области компьютерной алгебры). Против этого я ничего не имел.
66 |
Г пава 3 |
n=l; k=5; m= N [FractionalPart[10л (n-1)*Pi],k+10] 0.141592653589793
n=2; k=5; m= N [FractionalPart[10A (n-1)*Pi],k+10] 0.415926535897932
n=10; k=5; m= N [FractionalPart[10*(n-1)*Pi] ,k+10] 0.589793238462643
и сверить результаты с таблицами. Как легко убедиться, результаты совпадают, так что беспокоиться вроде бы не о чем. Но вот если положить п = 50, появляется преду преждение о недостаточной разрядности.
N::meprec: Internal precision limit $MaxExtraPrecision = 50. reached while evaluating -
31415926535897 « 2 1 » 841971693993751 « 1 » « 1 » .
А при n = 1000 результат выглядит вообще странно: 0.x10м , да и предупреждений целых два! Давайте разберемся, в чем тут дело. Для этого придется проанализировать ход вычислений. Сначала вычисляется Pi с некоторой точностью, притом с запасом (не более $MaxExtraPrecision десятичных знаков, как следует из предупреждения), а затем это число умножается на степень 10, так что в итоге получается 10Л (n-1) *Pi с некоторой точностью, после чего мы пытаемся взять у этого полученного числа его дробную часть. Но вот теперь и оказывается, что число было вычислено с недостаточ ной точностью, и система Mathematica предупреждает об этом! Впрочем, выход оче виден: нужно просто увеличить значение $MaxExtraPrecision. Но увеличение будет весьма значительным, и потому лучше всего сделать так, чтобы увеличенное значение $MaxExtraPrecision использовалось системой Mathematica только при вычислении результата, нужного для функции FractionalPart. Иными словами, увеличенное значение $MaxExtraPrecision нужно сделать локальным. Для этого достаточно вос пользоваться функцией Block. Тогда можно написать следующую тестовую программу.
Do [Block[{ k=10},Block[{$MaxExtraPrecision = n+k+10},
Print[n+1,":", N [FractionalPart[10An*Pi],k+10]]]],{n,0,2030,5}]
Едва ли стоит полностью приводить распечатку результата, но вот отдельные ее части явно заслуживают обсуждения. Вот банальное начало, подтверждающее пра вильность задания в программе степеней, умножений и всей подобной тривиальной чепухи, в записи которой так легко допустить ошибку.
I |
0.14159265358979323846 |
6 |
0.26535897932384626434 |
II |
0.89793238462643383280 |
16 |
0.23846264338327950288 |
21 |
0.26433832795028841972 |
26 |
0.83279502884197169399 |
31 |
0.50288419716939937511 |
36 |
0.41971693993751058210 |
Правильность цифр можно проверить по таблицам, имеющимся почти в любом солидном справочнике по математике или в какой-нибудь монографии, посвященной арифметике произвольной разрядности, например во втором томе бессмертного труда Дональда Кнута Искусство программирования. Что касается продолжения распечатки, то в ней правильность цифр проверить уже сложнее. Ведь найти книгу с более чем пятидесятью знаками л существенно сложнее. Из опыта знаю, что на территории
СССР научному сотруднику, не связанному со спецслужбами вроде КГБ или ГРУ, получить доступ к серьезному фолианту по истории вычисления к практически было невозможно. Тем больше наша благодарность организатору первых математических олимпиад в Ленинграде (и СССР; первые олимпиады в Москве и Киеве проводились
Числа, их представление и операции над ними |
67 |
только через год) Василию Августовичу Кречмару, который в последних изданиях своего труда Задачник по алгебре (предназначенного для любознательных школьни ков!) поместил результат вычисления п с 2035 знаками после запятой. Разрабатывая арифметику произвольной разрядности для различных программных комплексов (в том числе и систем компьютерной алгебры), я при проверке получаемых результа тов неоднократно пользовался шестым изданием этого бестселлера. Вполне подойдет эта книга и для проверки (хотя бы и выборочной) результатов, выдаваемых нашей программой. Так что можем читать нашу распечатку дальше.
41 |
0,69399375105820974945 |
46 |
0.37510582097494459231 |
51 |
0.58209749445923078164 |
56 |
0.74944592307816406286 |
61 |
0.59230781640628620900 |
66 |
0.78164062862089986280 |
71 |
0.062862089986280348253 |
76 |
0.20899862803482534212 |
81 |
0.86280348253421170680 |
86 |
0.34825342117067982148 |
91 |
0.34211706798214808651 |
96 |
0..706798214 80865132823 |
101 |
0.82148086513282306647 |
106 |
0.086513282306647093845 |
Вы заметили, что распечатан один “лишний” знак? А знаете, почему? Продолжаем читать дальше.
111 |
0.32823066470938446096 |
116 |
0.066470938446095505822 |
1210.093844609550582231725
Ивот опять появились “лишние” знаки. Правда, и в этом случае после точки сто ит сразу 0. Но не случайность ли это?
126 0.46095505822317253594
131 0.50582231725359408128
136 0.2317253594081284В112
141 0.53594081284811174503
1460.081284811174502841027
Ивот опять появился “лишний” знак. И опять после точки стоит сразу 0. Да не закономерность ли это? Давайте пропустим часть распечатки и поищем еше “лишние” знаки (я выделяю их курсивом, знак после точки — полужирным).
286 |
0.60726024914127372459 |
|
291 |
0.024914127372458700661 |
|
296 |
0.41273724587006606316 |
|
301 |
0.72458700660631558817 |
|
306 |
0.70066063155881748815 |
|
311 |
0.063155881748815209210 |
|
316 |
0.58817488152092096283 |
|
356 |
0.90360011330530548820 |
|
361 |
0.011330530548820466521 |
|
366 |
0.053054882046652138415 |
1 |
371 |
0.48820466521384146952 |
|
416 |
0.91953092186117381933 |
|
421 |
0.092186117381932611793 |
|
426 |
0.61173819326117931051 |
|
О, действительно, это, должно быть, закономерность. Итак, мы полагаем, что если после точки идет нуль, то вычисляется дополнительная цифра. Ну а если нулей не сколько? Может быть, количество ведущих нулей равно количеству “лишних” цифр? Давайте попробуем подтвердить (или опровергнуть) эту гипотезу.
446 |
0.18548074462379962750 |
451 |
0.074462379962749567352 |
456 |
0.23799627495673518858 |
556 |
0.70277053921717629318 |
561 |
0.053921717629317675234 |
566 |
0.17176293176752384675- |
591 |
0.76694051320005681271 |
596 |
0.051320005681271452636 |
601 |
0.0005681271452 6356082 779 |
606 |
0.81271452635608277858 |
741 |
0.47713099605187072113 |
746 |
0.099605187072113500000 |
751 |
0.51870721134999999837 |
776 |
0.49951059731732816096 |
781 |
0.059731732816096318595 |
786 |
0.17328160963185950245 |
851 |
0.71010003137838752887 |
856 |
0.0031378387528865875332 |
861 |
0.78387528865875332084 |
991 |
0.21642019893809525720 |
996 |
0.019893809525720106549 |
1041 |
0.82303019520353018530 |
1046 |
0.019520353018529689958 |
1051 |
0.035301852968995773623 |
1111 |
0.45415069595082953312 |
1116 |
0.069595082953311686173 |
1121 |
0.50829533116861727856 |
1166 |
0.19255060400927701671 |
1171 |
0.060400927701671139010 |
1176 |
0.092770167113900984882 |
1181 |
0.016711390098488240129 |
1266 |
0.6847104 047.5346462080 |
1271 |
0.040475346462080466843 |
1276 |
0.53464620804668425907 |
1331 |
0.66024058038150193511 |
1336 |
0.058038150193511253382 |
1386 |
0.92726042699227967824 |
1391 |
0.042699227967823547816 |
1516 |
0.75596023648066549912 |
Числа, их представление и операции над ними |
69 |
1521 |
0 . 0 2 3 6 4 8 0 6 6 5 4 9 9 1 1 9 8 8 1 8 3 |
1551 |
0.63698074265425278626 |
1556 |
0.074265425278625518184 |
1601 |
0.81647060016145249192 |
1606 |
0.060016145249192173217 |
1756 |
0.67179049460165346680 |
1761 |
0.049460165346680498863 |
1766 |
0.016534668049886272328 |
1831 |
0.95068006422512520512 |
1836 |
0.0064225125205117392985 |
1856 |
0.84896084128488626946 |
1861 |
0.084128488626945604242 |
1896 |
0.11863067442786220392 |
1901 |
0.067442786220391949450 |
1916 |
0.94945047123713786961 |
1921 |
0.047123713786960956364 |
1966 |
0.41389086583264599581 |
1971 |
0.086583264599581339048 |
2021 0.98352595709825822621
2026 0.59570982582262052249
2031 0.98258226205224894077
Итак, все говорит о том, что эта гипотеза верна! А знаете, почему? Потому что ве дущие нули не учитываются при подсчете значащих цифр (а ведь именно их количестве и равно разрядности). “Ну, это я знал с шестого класса, если не с пеленок. Давайте лучше решим задачу до конца, раз уж мы столь тщательно проверили предложен ный мною вариант программы и убедились в его правильности!” — воскликнет иной искушенный читатель. Что же, не возражаю. Давайте зададим параметры и по лучим результат.
Do[Block[{ k=1000},Block[{$MaxExtraPrecision = n+k+10},
Print[n+1,":",N[FractionalPart[10An*Pi],k+1]]]],{n,9 9 9 9 9 , 9 9 9 9 9 } ]
100000 :
0 .6 4 1 2 6 0 0 2 4 3 7 9 6 8 4 5 4 3 7 7 7 3 3 9 0 2 6 4 7 2 5 1 2 8 1 9 4 1 6 3 2 0 0 7 6 8 4 8 7 3 6 2 5 1 7 6 4 0 6 5 9 6 7 5 4 0 6 9 36217588793 0 7 8 5 5 9 1 6 4 7 8 7 7 7 2 7 4 7 3 9 2 7 2 0 0 2 9 1 0 3 4 2 9 4 9 5 6 2 4 4 7 6 6 1 3 0 8 2 0 0 7 2 9 2 5 0 7 3 4 52917076 4 2 2 6 6 2 1 0 4 7 6 7 3 0 3 7 8 6 3 1 6 9 9 5 4 2 3 7 4 5 5 1 1 7 4 5 6 5 2 2 0 2 2 7 8 3 3 2 4 0 9 6 8 0 3 5 2 4 6 6 7 6 63190861011206745856 2 8 7 3 1 7 4 1 3 5 1 1 1 6 2 2 9 2 0 7 8 8 6 5 1 3 2 9 4 1 2 4 4 8 1 5 4 7 1 6 2 8 1 8 2 0 7 9 8 7 7168346341322 3 6 2 2 3 4 1 1 7 7 8 8 2 3 1 0 2 7 6 5 9 8 2 5 1 0 9 3 5 8 8 9 2 3 5 9 1 6 2 0 5 5 1 0 8 7 6 3 2 9 8 0 8 7 9 9 3 16517252893800123781 7 4 3 4 8 9 6 8 3 2 1 5 1 5 9 0 5 6 2 4 9 3 3 4 7 3 7 0 2 0 6 8 3 2 2 3 2 1 0 0 1 1 8 6 3 7 3 9 5 7 705674738671021732 1 2 3 7 5 2 2 4 3 2 5 2 4 1 6 2 6 3 5 8 0 3 4 3 7 6 2 5 3 6 0 6 8 0 8 6 6 9 1 6 3 5 7 1 5 9 4 5 5 1 5 2 78178039217743228234 3 6 6 3 3 7 7 2 8 1 1 1 8 6 3 9 0 5 1 1 8 9 3 0 7 5 9 0 1 6 6 6 6 5 0 7 4 2 9 5 2 7 5 8 3 8 4 0 0 8 54463541931719053136 3 6 5 9 7 2 4 9 0 5 1 5 8 4 0 9 1 0 6 5 8 2 2 0 1 8 1 4 7 3 4 7 9 9 0 2 2 3 5 9 0 6 7 1 3 8 1 4 6 9 051160519223012694823161134174 3 9 9 4 4 7 1 4 8 3 3 0 4 0 8 6 2 4 8 4 2 6 9 1 3 9 5 0 2 3 3 6 7 1 3 4 1 2 4 2 512386402665725813094396762 1 9 3 9 6 5 5 4 0 7 3 8 6 5 2 4 2 2 9 8 9 7 8 7 9 7 8 2 1 9 8 6 3 7 9 1 8 2 9 9 7 0 9 55792474732030323911641044590690 7 9 7 7 8 6 2 3 1 5 5 1 8 3 4 9 5 9 3 0 3 5 3 0 5 9 2 3 7 8 9 8 1 7 5 1 5 8 9 1 4 5 7 6 5 0 4 0 8 0 2 5 1 0 9 4 7 9 1 2 3 4 2 1 7 5 8 48284188195013854616568030175503558005494 4 8 9 4 8 8 4 8 7 1 3 5 1 6 0 5 3 7 5 5 9 3 4 0 2 3 4 5 7 4 8 9 7 9 516602442338321406030095937105588457 0 5 2 5 1 5 7 0 4 2 6 6 2 8 4 6 0 0 3 5 4 4 0
70 |
Глава 3 |
Полужирным здесь выделены искомая сто первая тысяча цифр в представлении числа п десятичной дробью, причем первая выделенная цифра является стотысячной после запятой. “Ну вот, и все дела. Я сразу говорил, что нужно применить функцию FractionalPart. А автор все сомневался, проверял тривиальную программу, срав нивал десятичные знаки с предварительно вычисленными значениями л, измышлял гипотезы... Да в этой программе Pi можно заменить любым числом, в конце кон цов, я такие программы пишу с пеленок!” — возмутится тут искушенный читатель. Ой, не торопитесь делать такие выводы. В математике (и в программировании, и в компьютерной алгебре) есть великие идеи, но нет мелочей. А что касается вещест венных чисел, то они свои ловушки расставляют не только на страницах учебников по теории функций вещественного переменного (чтобы изловить ленивых студен тов), но и в вполне респектабельных программах (чтобы в эти ловушки на сей раз угодили “искушенные” читатели и нерадивые пользователи). Вспомните, что мы в ходе проверки подтвердили гипотезу о том, что количество ведущих нулей равно коли честву “лишних” цифр. Но ведь мы заранее не знаем, сколько ведущих нулей может встретиться при вычислении дробной части FractionalPart [10An*Pi], так что за ранее ручаться за правильный выбор разрядности мы не могли! Нам просто повез ло, что выбранное значение разрядности обеспечило нужную точность! В принципе заранее неизвестно, работает ли наша программа для всех натуральных значений п и к. Указанного нами значения $MaxExtraPrecision = n+k+10 может ведь и не хватить для вычисления к+10 значащих цифр дробной части, если она будет начи наться более, чем с десяти нулей! Если бы в десятичном приближении к встреча лись сколь угодно длинные последовательности нулей, то для каждого к нашлось бы такое п, что программа с задачей не справилась бы! К счастью для “искушенного” читателя в настоящий момент это неизвестно. Зато даже шестиклассник (во всяком случае, участник районных математических олимпиад) без труда может придумать примеры вещественных чисел, для которых эта программа и ей подобные не рабо тают. Нужно просто выбрать число, в десятичной записи которого встречаются все более длинные последовательности нулей. В качестве примера подойдет число
0.1234567891011121314151617181920..., в котором после десятичной точки выписа ны последовательно все натуральные числа. Есть, конечно, и более экзотические примеры, что-нибудь вроде
Е'^КГ7ЭС 1 0,1100010....
Десятичная запись этого числа содержит только нули и единицы, причем и тех, и других там бесконечно много, но единицы встречаются столь редко, что если наудачу выберешь какую-нибудь цифру, почти наверняка попадешь на последовательность нулей. Так что слухи о том, что придуманная нами программа при тривиальных мо дификациях может быть применена к любому вещественному числу, были несколько преувеличены...
Да, а как же все-таки решить задачу? Ну, в данном случае это совсем несложно.
Block[{ k=1000,п = 9 9 9 9 9 } ,N [FractionalPart[N[10An*Pi,n+k+10]],к+1]]
0 .6 4 1 2 6 0 0 2 4 3 7 9 6 8 4 5 4 3 7 7 7 3 3 9 0 2 6 4 7 2 5 1 2 8 1 9 4 1 6 3 2 0 0 7 6 8 4 8 7 3 6 2 5 1 7 6 4 0 6 5 9 6 7 5 4 0 6 9 3 6 2 1 7 5 8 8 7 9 3 0 7 8 5 5 9 1 6 4 7 8 7 7 7 2 7 4 7 3 9 2 7 2 0 0 2 9 1 0 3 4 2 9 4 9 5 6 2 4 4 7 6 6 1 3 0 8 2 0 0 7 2 9 2 5 0 7 3 4 5 2 9 1 7 0 7 6 4 2 2 6 6 2 1 0 4 7 6 7 3 0 3 7 8 6 3 1 6 9 9 5 4 2 3 7 4 5 5 1 1 7 4 5 6 5 2 2 0 2 2 7 8 3 3 2 4 0 9 6 8 0 3 5 2 4 6 6 7 6 631908 6 1 0 1 1 2 0 6 7 4 5 8 5 6 2 8 7 3 1 7 4 1 3 5 1 1 1 6 2 2 9 2 0 7 8 8 6 5 1 3 2 9 4 1 2 4 4 8 1 5 4 7 1 6 2 8 1 8 2 0 7 9 8 7 7 1 6 8 3 4 6 3 4 1 3 2 2 3 6 2 2 3 4 1 1 7 7 8 8 2 3 1 0 2 7 6 5 9 8 2 5 1 0 9 3 5 8 8 9 2 3 5 9 1 6 2 0 5 5 1 0 8 7 6 3 2 9 8 0 8 7 9 9 3 1 6 5 1 7 2 5 2 8 9 3 8 0 0 1 2 3 7 8 1 7 4 3 4 8 9 6 8 3 2 1 5 1 5 9 0 5 6 2 4 9 3 3 4 7 3 7 0 2 0 6 8 3 2 2 3 2 1 0 0 1 1 8 6 3 7 3 9 5 7 7 0 5 6 7 4 7 3 8 6 7 1 0 2 1 7 3 2 1 2 3 7 5 2 2 4 3 2 5 2 4 1 6 2 6 3 5 8 0 3 4 3 7 6 2 5 3 6 0 6 8 0 8 6 6 9 1 6 3 5 7 1 5 9 4 5 5 1 5 2 7 8 1 7 8 0 3 9 2 1 7 7 4 3 2 2 8 2 3 4 3 6 6 3 3 7 7 2 8 1 1 1 8 6 3 9 0 5 1 1 8 9 3 0 7 5 9 0 1 6 6 6 6 5 0 7 4 2 9 5 2 7 5 8 3 8 4 0 0 8 5 4 4 6 3 5 4 1 9 3 1 7 1 9 0 5 3 1 3 6 3 6 5 9 7 2 4 9 0 5 1 5 8 4 0 9 1 0 6 5 8 2 2 0 1 8 1 4 7 3 4 7 9 9 0 2 2 3 5 9 0 6 7 1 3 8 1 4 6 9
Числа, их представление и операции над ними |
71 |
0 5 1 1 6 0 5 1 9 2 2 3 0 1 2 6 9 4 8 2 3 1 6 1 1 3 4 1 7 4 3 9 9 4 4 7 1 4 8 3 3 0 4 0 8 6 2 4 8 4 2 6 9 1 3 9 5 0 2 3 3 6 7 1 3 4 1 2 4 2
5 1 2 3 8 6 4 0 2 6 6 5 7 2 5 8 1 3 0 9 4 3 9 6 7 6 2 1 9 3 9 6 5 5 4 0 7 3 8 6 5 2 4 2 2 9 8 9 7 8 7 9 7 8 2 1 9 8 6 3 7 9 1 8 2 9 9 7 0 9
5 5 7 9 2 4 7 4 7 3 2 0 3 0 3 2 3 9 1 1 6 4 1 0 4 4 5 9 0 6 9 0 7 9 7 7 8 6 2 3 1 5 5 1 8 3 4 9 5 9 3 0 3 5 3 0 5 9 2 3 7 8 9 8 1 7 5 1 5 8
9 1 4 5 7 6 5 0 4 0 8 0 2 5 1 0 9 4 7 9 1 2 3 4 2 1 7 5 8 4 8 2 8 4 1 8 8 1 9 5 0 1 3 8 5 4 6 1 6 5 6 8 0 3 0 1 7 5 5 0 3 5 5 8 0 0 5 4 9 4
4 8 9 4 8 8 4 8 7 1 3 5 1 6 0 5 3 7 5 5 9 3 4 0 2 3 4 5 7 4 8 9 7 9 5 1 6 6 0 2 4 4 2 3 3 8 3 2 1 4 0 6 0 3 0 0 9 5 9 3 7 1 0 5 5 8 8 4 5 7
0 5 2 5 1 5 7 0 4 2 6 6 2 8 4 6 0 0 3 5 4 4 0
Почему же все-таки я подчеркиваю, что решить задачу несложно именно в данном
случае? Вспомните пример с Там проблема была в том, что вычисленные деся тичные приближения заканчивались девятками. А если бы и в этом примере цифры в конце оказались девятками, мы бы не смогли решить, верные ли они. (Именно для того, чтобы избежать округления и убедиться, что последняя цифра не девятка, мы и распечатываем к+1 цифру — к требуемых по условию задачи и одну запасную. Если бы запасная цифра оказалась девяткой, пришлось бы выводить еще несколько запас ных цифр, пока не обнаружили бы отличную от 9.) Конечно, мы могли бы увеличить разрядность, но что если бы мы повстречали участок, сплошь состоящий из несколь ких миллионов девяток? Может быть, это верные цифры, а может быть, нам просто не хватило точности, и в каком-то миллионе затерялась та единичка в переносе, до бавление которой превращает все эти миллионы девяток в миллионы нулей? Вот оно коварство бесконечных десятичных дробей!
Из этого можно извлечь несколько уроков. Во-первых, выполняя действия над вещественными числами, нужно тщательно следить за точностью. Во-вторых, для применения таких функций, как FractionalPart, иногда необходима существенно более высокая разрядность, чем та, которая обеспечивается системой автоматически. В-третьих, иногда перестановка функций позволяет упростить программу. И, нако нец, в-четвертых, вещественные числа иногда способны преподносить сюрпризы вро де девяток в конце вычисленных значений или необъятного количества ведущих ну лей в начале дробной части. Тогда даже на простые вопросы вроде целое ли это число или конечная ли эта десятичная дробь ответить бывает чрезвычайно трудно. Ведь чем точнее удается приблизить бесконечную дробь рациональными числами, тем больше шансов на то, что она представляет собой число трансцендентное...
Упражнение 3.2 (число Пизо). Вычислите 5555 десятичных цифр числа Пизо
Сколько у этого числа нулей следует сразу после десятичной точки?
Решение. Вот самое простое решение. Сначала вводим определение числа.
P is o t N u m b e r =
|
|
|
|
30000 |
|
|
|
1 з/ |
27 + 3 V69 |
27 + 3 л/б? |
+i V — |
|||
\ 1/3 |
|
-1 |
-1 |
1/3\ 30000 |
27 + 3 л/69 ) |
+ 4 |
(у |
(27 + 3 V69)) |
|
|
3 |
^ 2 |
|
Теперь вычисляем число с указанной точностью.
N[PisotNumber, 5555] 5.04316596065665493215059469242757481077610274680893503167844467712875 7182264862106103980765819340682753857825408213309478700354777871766946 859877182545765655157863751804030841080877201973602630453775992992526С 0787464343711547834066265665424226316713797047087646002867659572088255
72 |
Гпава 3 |