Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

книги / Mathematica 5. ╨б╨░╨╝╨╛╤Г╤З╨╕╤В╨╡╨╗╤М

.pdf
Скачиваний:
1
Добавлен:
19.11.2023
Размер:
33.75 Mб
Скачать

Таким образом, функция 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