Дробная часть вещественного числа (функция FractionalPart)
Как легко убедиться, результаты совпадают, так что беспокоиться вроде бы не о чем. Но вот если положить n = 50, появляется предупреждение о недостаточной разрядности.
N::meprec: Internal precision limit $MaxExtraPrecision
=
50
.
reached
while
evaluating
-
31415926535897
"21"
841971693993751
"1"
"1"
.
А при n = 1000 результат выглядит вообще странно: 0.х1034, да и предупреждений целых два! Давайте разберемся, в чем тут дело. Для этого придется проанализировать ход вычислений. Сначала вычисляется Pi с некоторой точностью, притом с запасом (не более $MaxExtraPrecision десятичных знаков, как следует из предупреждения), а затем это число умножается на степень 10, так что в итоге получается 10^ (n-l) *Pi с некоторой точностью, после чего мы пытаемся взять у этого полученного числа его дробную часть. Но вот теперь и оказывается, что число было вычислено с недостаточной точностью, и система Mathematica предупреждает об этом! Впрочем, выход очевиден: нужно просто увеличить значение $MaxExtraPrecision. Но увеличение будет весьма значительным, и потому лучше всего сделать так, чтобы увеличенное значение $MaxExtraPrecision использовалось системой Mathematica только при вычислении результата, нужного для функции FractionalPart. Иными словами, увеличенное значение $MaxExtraPrecision нужно сделать локальным. Для этого достаточно воспользоваться функцией Block. Тогда можно написать следующую тестовую программу.
Do[Block[{k
=
10
}, Block[{$MaxExtraPrecision
=
n
+
k
+
10
), Print[n
+
1
,
":"
, N[FractionalPart[
10
^
n
*
Pi], k
+
10
]]]], {n,
0.2030.5
}]
Едва ли стоит полностью приводить распечатку результата, но вот отдельные ее части я в но заслуживают обсуждения. Вот банальное начало, подтверждающее правильность задания в программе степеней, умножений и всей подобной тривиальной чепухи, в записи которой так легко допустить ошибку.
1
:
0.14159265358979323846
6
:
0.26535897932384626434
11
0.89793238462643383280
16
0.23846264338327950288
21
0.26433832795028841972
26
0.83279502884197169399
31
0.50288419716939937511
36
0.41971693993751058210
Правильность цифр можно проверить по таблицам, имеющимся почти в любом солидном справочнике по математике или в какой-нибудь монографии, посвященной арифметике произвольной разрядности, например во втором томе бессмертного труда Дональда Кнута Искусство программирования. Что касается продолжения распечатки, то в ней правильность цифр проверить уже сложнее. Ведь найти книгу с более чем пятидесятые знаками л существенно сложнее. Из опыта знаю, что на территории СССР научному сотруднику, не связанному со спецслужбами вроде КГБ или ГРУ, получить доступ к серьезному фолианту по истории вычисления я практически было невозможно. Тем больше наша благодарность организатору первых математических олимпиад в Ленинграде (и СССР; первые олимпиады в Москве и Киеве проводились только через год) Василию Августовичу Кречмару, который в последних изданиях своего труда Задачник по алгебре (предназначенного для любознательных школьников!) поместил результат вычисления π с 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.70679821480865132823
101
:
0.82148086513282306647
106
:
0.086513282306647093845
Вы заметили, что распечатан один "лишний" знак? А знаете, почему? Продолжаем читать дальше.
111
:
0.32823066470938446096
116
:
0.066470938446095505822
121
:
0.093844609550582231725
И вот опять появились "лишние" знаки. Правда, и в этом случае после точки стоит сразу 0. Но не случайность ли это?
126
:
0.46095505822317253594
131
:
0.50582231725359408128
136
:
0.23172535940812848112
141
:
0.53594081284811174503
146
:
0.081284811174502841027