Code covered by the BSD License  

Highlights from
HPF - a big decimal class

HPF - a big decimal class

by

 

04 May 2012 (Updated )

High precision floating point arithmetic, a new class written in MATLAB

Demo script for my High Precision Floating point decimal

Demo script for my High Precision Floating point decimal

format. The user can specify any number of digits to be carried, while doing a variety of different numerical computations on these numbers. Not all MATLAB operators are defined, as my main goal here was merely to build a general tool for this purpose while learning to use MATLAB's OOP facilities. As well, it seems a useful tool to learn how one MIGHT accomplish the goal of a "big" float format.

Considerably more information is provided in the document HPF.pdf, where I provide many details of the computational methods employed in HPF.

Author: John D'Errico e-mail: woodchips@rochester.rr.com

Contents

Create a hpf number at the command line

Note that you don't need to specify the number of digits in advance. HPF has a default of 66 total digits, 2 of which are shadowed, carried as guard digits, but not reported.

DefaultNumberOfDigits 64 2
F = hpf(12)
F =
12

There are 66 digits carried in this format by default, two of which are generally hidden from view.

F.NumberOfDigits
ans =
    64     2

Note that the number 12 is an integer in MATLAB, so it is exactly convertable in the hpf format. Next, convert a true floating point number into hpf form.

F = hpf(1.2)
F =
1.199999999999999955591079014993738383054733276367187500000000000

As we see here, the number was not truly exactly 1.2. This happens because I let MATLAB create the value 1.2, which is then passed into hpf and then converted into the decimal form for that number from the hex form carried internally. The digits here are the exact representation of that number as MATLAB has stored it in the ieee form. In fact, the last 40 digits are essentially random floating point trash. Also see that this number has a few trailing zeros.

mantissa(F)
ans =
  Columns 1 through 13
     1     1     9     9     9     9     9     9     9     9     9     9     9
  Columns 14 through 26
     9     9     9     9     5     5     5     9     1     0     7     9     0
  Columns 27 through 39
     1     4     9     9     3     7     3     8     3     8     3     0     5
  Columns 40 through 52
     4     7     3     3     2     7     6     3     6     7     1     8     7
  Columns 53 through 65
     5     0     0     0     0     0     0     0     0     0     0     0     0
  Column 66
     0

Had we specified F in a different way, we could have generated the exact decimal form. Thus

F = hpf('1.2')
F =
1.2

This number is the exact representation of the desired decimal value. A nice feature of HPF is that it will parse anumber with a long string of decimal digits correctly. Thus we can provide a number with many digits and expect that hpf will store all of them exactly as we desire.

F = hpf('123.45678909876543210123456789098765432101234567890987654321012345',[100 0])
F =
123.45678909876543210123456789098765432101234567890987654321012345

since we requested exactly 100 digits in the result, there are zeros appended to the end of the digit string.

mantissa(F)
ans =
  Columns 1 through 13
     1     2     3     4     5     6     7     8     9     0     9     8     7
  Columns 14 through 26
     6     5     4     3     2     1     0     1     2     3     4     5     6
  Columns 27 through 39
     7     8     9     0     9     8     7     6     5     4     3     2     1
  Columns 40 through 52
     0     1     2     3     4     5     6     7     8     9     0     9     8
  Columns 53 through 65
     7     6     5     4     3     2     1     0     1     2     3     4     5
  Columns 66 through 78
     0     0     0     0     0     0     0     0     0     0     0     0     0
  Columns 79 through 91
     0     0     0     0     0     0     0     0     0     0     0     0     0
  Columns 92 through 100
     0     0     0     0     0     0     0     0     0

Be careful though, since if you provide many digits, but then indicate that only a few digits be stored, then I'll do as you tell me, truncating the extra digits from that number.

F = hpf('123.45678909876543210123456789098765432101234567890987654321012345',[10 0])
mantissa(F)
F =
123.4567890
ans =
     1     2     3     4     5     6     7     8     9     0

Note that the digits of F are stored as Migits, with an initial default set as 4-migits

DefaultDecimalBase
ans =
     1

We can see the migits themselves

F.Migits
ans =
     1     2     3     4     5     6     7     8     9     0

Numbers are stored in a floating point form, with a separate sign and exponent from the Mantissa. The sign is stored as either -1, 0 or 1. We can extract the sign directly.

F.Sign
ans =
     1

Extracting the exponent is also easily done.

F.Exponent
ans =
                    3

That exponent is stored as an int64 integer, so numbers as large in magnitude as the largest int64 number can be formed and manipulated.

intmax('int64')
ans =
  9223372036854775807

HPF does include both Inf and NaN as permissable values.

hpf(inf)
hpf(nan)
ans =
  Inf
ans =
  NaN

In some cases a computation can have a problem. So just as 0/0 produces a NaN in matlab, it does so with HPF numbers too. The latter two examples here create HPF NaNs.

0/0
hpf(0)/0
hpf(0)/hpf(0)
ans =
   NaN
ans =
  NaN
ans =
  NaN

Inf is as easily generated, even by some functions. As large as the exponent in any floating point form can be, we can always overflow that value if we try hard enough.

1/0
hpf(1)/0
cot(hpf(0))
tan(hpf('pi',[64 1])/2)
exp(hpf('1e1000'))
ans =
   Inf
ans =
  Inf
ans =
  Inf
ans =
  Inf
ans =
  Inf

Most numeric classes are currently supported for conversion into a hpf format, with the exception of complex numbers. (Sorry, perhaps in a future version.)

Special numbers in hpf

The numbers pi and e are useful enough that I'm willing to store the true value for those digits, up to a realistic limit. Thus, there are 100000 digits available for pi, and 100000 digits stored away for e.

Here I will define a 100 digit version of the number pi. Of course, I cannot simply type hpf(pi), as that would convert the double precision version of pi that MATLAB supplies into a hpf. Instead, HPF looks for 'pi' and 'e' as keys here.

PI = hpf('pi',100)
PI =
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068

Properties of a hpf number

properties('hpf')
Properties for class hpf:
    NumberOfDigits
    DecimalBase
    Base
    Numeric
    Sign
    Exponent
    Migits

Methods currently defined for hpf numbers.

(This will grow with time of course.)
methods('hpf')
Methods for class hpf:

abs                cscd               isnumeric          sec                
acos               csch               iszero             secd               
acosd              cubrt              le                 sech               
acosh              cumprod            linspace           sign               
acot               cumsum             log                sin                
acotd              disp               log10              sind               
acsc               display            log2               single             
acscd              double             lt                 sinh               
adjustdecimalbase  eps                mantissa           sort               
asec               eq                 max                sqrt               
asecd              erf                min                sum                
asin               exp                minus              tan                
asind              factorial          mod                tand               
asinh              fix                mpower             tanh               
atan               floor              mrdivide           times              
atand              fractionalpart     mtimes             uint16             
atanh              ge                 ne                 uint32             
augmentdigits      gt                 nthroot            uint64             
ceil               hpf                num2str            uint8              
cos                int16              plus               uminus             
cosd               int32              power              uplus              
cosh               int64              prod               vpi                
cot                int8               rdivide            
cotd               isfinite           reciprocal         
coth               isinf              round              
csc                isnan              roundn             

Static methods:

eye                ten                
ones               zeros              

Arithmetic operations are defined on a hpf number

2*PI
ans =
6.283185307179586476925286766559005768394338798750211641949889184615632812572417997256069650684234136

So if we subtract the value of 2*pi, as defined by MATLAB, we expect a result that is on the order of eps.

2*PI - 2*pi
ans =
0.0000000000000002449293598294706354452131864550002116419498891846156328125724179972560696506842341359600000000000000

Many of the standard functions in mathematics have been defined for hpf numbers

For example, I could get 100 digits in the value of e as simply

e_100 = hpf('e',100)
e_100 =
2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427

But I could have also found that value as

exp(hpf(1,100))
ans =
2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427

Changing the number of digits in an hpf number

We can specify the number of digits to be carried in an hpf number in a variety of ways.

First, I'll define 1/3 as a hpf number, with 100 decimal digits shown. in fact, there will be 104 digits stored, the last four of which are simply there to be conservative, for an extra bit of accuracy.

F = hpf('1',100)/3
F.Migits
F.NumberOfDigits
F =
0.3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333
ans =
  Columns 1 through 13
     3     3     3     3     3     3     3     3     3     3     3     3     3
  Columns 14 through 26
     3     3     3     3     3     3     3     3     3     3     3     3     3
  Columns 27 through 39
     3     3     3     3     3     3     3     3     3     3     3     3     3
  Columns 40 through 52
     3     3     3     3     3     3     3     3     3     3     3     3     3
  Columns 53 through 65
     3     3     3     3     3     3     3     3     3     3     3     3     3
  Columns 66 through 78
     3     3     3     3     3     3     3     3     3     3     3     3     3
  Columns 79 through 91
     3     3     3     3     3     3     3     3     3     3     3     3     3
  Columns 92 through 102
     3     3     3     3     3     3     3     3     3     3     3
ans =
   100     2

Reduce the number of digits in F

F = augmentdigits(F,[50,2])
F.NumberOfDigits
F =
0.33333333333333333333333333333333333333333333333333
ans =
    50     2

Of course, we can increase the number of digits stored again, but the information in those truncated digits is lost. Future computations will now be carried out with the new precision.

F = augmentdigits(F,[250,4])
F.NumberOfDigits
F.Migits
F =
0.3333333333333333333333333333333333333333333333333333
ans =
   250     4
ans =
  Columns 1 through 13
     3     3     3     3     3     3     3     3     3     3     3     3     3
  Columns 14 through 26
     3     3     3     3     3     3     3     3     3     3     3     3     3
  Columns 27 through 39
     3     3     3     3     3     3     3     3     3     3     3     3     3
  Columns 40 through 52
     3     3     3     3     3     3     3     3     3     3     3     3     3
  Columns 53 through 65
     0     0     0     0     0     0     0     0     0     0     0     0     0
  Columns 66 through 78
     0     0     0     0     0     0     0     0     0     0     0     0     0
  Columns 79 through 91
     0     0     0     0     0     0     0     0     0     0     0     0     0
  Columns 92 through 104
     0     0     0     0     0     0     0     0     0     0     0     0     0
  Columns 105 through 117
     0     0     0     0     0     0     0     0     0     0     0     0     0
  Columns 118 through 130
     0     0     0     0     0     0     0     0     0     0     0     0     0
  Columns 131 through 143
     0     0     0     0     0     0     0     0     0     0     0     0     0
  Columns 144 through 156
     0     0     0     0     0     0     0     0     0     0     0     0     0
  Columns 157 through 169
     0     0     0     0     0     0     0     0     0     0     0     0     0
  Columns 170 through 182
     0     0     0     0     0     0     0     0     0     0     0     0     0
  Columns 183 through 195
     0     0     0     0     0     0     0     0     0     0     0     0     0
  Columns 196 through 208
     0     0     0     0     0     0     0     0     0     0     0     0     0
  Columns 209 through 221
     0     0     0     0     0     0     0     0     0     0     0     0     0
  Columns 222 through 234
     0     0     0     0     0     0     0     0     0     0     0     0     0
  Columns 235 through 247
     0     0     0     0     0     0     0     0     0     0     0     0     0
  Columns 248 through 254
     0     0     0     0     0     0     0

Trig functions

The standard trigonometric functions are all defined (although I've probably missed your favorite special function as there are so many. I seem to be constantly adding new functions as I notice that one is missing.)

The sine of 30 degrees = pi/6 radians is 1/2

sin(hpf('pi',200)/6)
sind(hpf('30',1000))
ans =
0.5
ans =
0.5

The cosine of 45 degrees = pi/4 radians is sqrt(2)/2

C = cosd(hpf('45',500))
% and of course, the square of that number should be 1/2
C.^2
C =
0.70710678118654752440084436210484903928483593768847403658833986899536623923105351942519376716382078636750692311545614851246241802792536860632206074854996791570661133296375279637789997525057639103028573505477998580298513726729843100736425870932044459930477616461524215435716072541988130181399762570399484362669827316590441482031030762917619752737287514387998086491778761016876592850567718730170424942358019344998534950240751527201389515822712391153424646845931079028923155579833435650650780928449361862
ans =
0.5

The tangent of 45 degrees = pi/4 radians is 1

tand(hpf('pi',1000)/4)
atand(hpf('1',1000))
ans =
0.01370864253439405605227298869790930363121380384841842673544536711960521807164775059427280020891113254561562378582045422164719174631109765713950037630957898860802480020923765874675922829584873864221797843978765892606013704345929094437512442369399787095125097994006840738875250901794241128544100024806068605721788387338083182793243192696944371011114307326529305276957593055314700017836809662218854752179847180761861543376311460311997654051066068212362010944818083667667870312358230187038986881975475528319227379662049032167313596293521706598712408936830751971770520631033465064783718752512525241556030042759546136161110199432687468919207329256921678814504836256955001984830490726781332113305296750494156109972970571233516623036276312379019005767225536128258770802849775452059663312639073442324922770841878513726292896357741375245258143298927264569637440177459635257380514260980739539297643828167434020129368034683562815450708160231110620759427376454042367056840328205686160894406218718726859525538377348
ans =
45

Basic arithmetic is provided, and much more.

As long as one term in the expression is an HPF number, the computation is done with an HPF result. Be careful though. Here I forced 5 to be an hpf number, with the current DefaultNumberOfDigits, because then I took a square root of 5. I can add an integer to that, since HPF converts 1 on the fly into HPF.

DefaultNumberOfDigits 64 4
phi = (1 + sqrt(hpf(5)))/2
phi =
1.618033988749894848204586834365638117720309179805762862135448623

Beware however, that while the following result will be in HPF form, with the desired number of digits, that the result will be incorrect past the 16th digit or so, because here sqrt(5) is computed as a double precision number, and only then converted to an HPF form.

(hpf(1) + sqrt(5))/2
ans =
1.618033988749894902525738871190696954727172851562500000000000000

If you want to be confident that the number computed is accurate, then do it a second time, but with more digits of precision, using a few more spare digits in the number. Here, I'll subtract the more accurate result from phi. All the reported digits are identical to those from our original computation.

phi - (1 + sqrt(hpf(5,[64 10])))/2
ans =
-1.e-67

A test of some identities

Working in 1000 decimal digits, with no shadow digits to hide any flaws...

DefaultNumberOfDigits 1000 0
x = sqrt(hpf(rand))
x =
0.9892828966686721966588084771080621824110688603882805218291976507761175228204225101799137466253878240361945470262486684240768569954524105531730701086545205931786964611854371786887162442712878824952714218522130207897229835538575432135412360102239231708656977270761647996715616109641063060039313428768336797564295731066982008603087212560802420994238511423020220472147374667944779706406598826657877494654846781213030596374908477834912113410357422358712113975525436392195198497448160311554385822360976094042536993667732632881889080138573316111924303987890290749329119408547228244148245473795136337207927318477467880026356181160233525354449226080613678286594439417226551901330107832281709784063937202698270458383739496710706446274567542147248753443657106611811076879366393254233493697588062120601818105602292020272423527407609686283881667162746215921741679943497673582996884855186628787072089636666843403544602132769073891995862608142686157684839520114777530672698681942357641017860127605733437466850370872

Should be 1

sin(x).^2 + cos(x).^2
ans =
0.9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999996

Should be -2

(log(cosh(x)/exp(x) - 1/2) + log(hpf(2)))/x
ans =
-1.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999993

Computing pi

As I've shown, I already store the value of pi internally in HPF to a rather large number of digits. But, one could use HPF to compute pi yourself. Here I'll use Viete's formula to generate 64 digits of pi. http://en.wikipedia.org/wiki/Pi

a = sqrt(hpf(2,[64 3]));
b = a/2;
tol = 10*eps(b)
niter = 0;
while 1
  niter = niter + 1;
  a = sqrt(2 + a);
  b0 = b;
  b = b*a/2;

  if abs(b - b0) <= tol
    break
  end
end
piest = 2/b
tol =
1.e-66
piest =
3.141592653589793238462643383279502884197169399375105820974944592

It took niter iterations before it had converged to my specified tolerance.

niter
niter =
   109

As you can see, the approximation yields the same digits as those I have stored for pi.

hpf('pi',64)
ans =
3.141592653589793238462643383279502884197169399375105820974944592

Another choice might be Chudnovski's formula: http://en.wikipedia.org/wiki/Chudnovsky_algorithm

DefaultNumberOfDigits 5000 10
DefaultDecimalBase 5
a1 = hpf(13591409); % small integers, so exact
a2 = hpf(545140134);
a3 = hpf(640320);
a4 = a3.*a3.*a3;
num = hpf(1);
den = sqrt(a4);
tol = eps(num);
piinv = hpf(0);
k = 0;
while 1

  piterm = num.*(a1+a2.*k)./den;
  piinv = piinv + piterm;

  if abs(piterm) < tol
    break
  end

  k = k + 1;
  num = num.*prod(hpf(6*k+(-5:0)));
  den = den.*a4.*(3*k-2).*(3*k-1).*(3*k).*hpf(k).^3;

  num = -num;

end
piest = reciprocal(12.*piinv)
piest =
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632788659361533818279682303019520353018529689957736225994138912497217752834791315155748572424541506959508295331168617278558890750983817546374649393192550604009277016711390098488240128583616035637076601047101819429555961989467678374494482553797747268471040475346462080466842590694912933136770289891521047521620569660240580381501935112533824300355876402474964732639141992726042699227967823547816360093417216412199245863150302861829745557067498385054945885869269956909272107975093029553211653449872027559602364806654991198818347977535663698074265425278625518184175746728909777727938000816470600161452491921732172147723501414419735685481613611573525521334757418494684385233239073941433345477624168625189835694855620992192221842725502542568876717904946016534668049886272327917860857843838279679766814541009538837863609506800642251252051173929848960841284886269456042419652850222106611863067442786220391949450471237137869609563643719172874677646575739624138908658326459958133904780275900994657640789512694683983525957098258226205224894077267194782684826014769909026401363944374553050682034962524517493996514314298091906592509372216964615157098583874105978859597729754989301617539284681382686838689427741559918559252459539594310499725246808459872736446958486538367362226260991246080512438843904512441365497627807977156914359977001296160894416948685558484063534220722258284886481584560285060168427394522674676788952521385225499546667278239864565961163548862305774564980355936345681743241125150760694794510965960940252288797108931456691368672287489405601015033086179286809208747609178249385890097149096759852613655497818931297848216829989487226588048575640142704775551323796414515237462343645428584447952658678210511413547357395231134271661021359695362314429524849371871101457654035902799344037420073105785390621983874478084784896833214457138687519435064302184531910484810053706146806749192781911979399520614196634287544406437451237181921799983910159195618146751426912397489409071864942319615679452080951465502252316038819301420937621378559566389377870830390697920773467221825625996615014215030680384477345492026054146659252014974428507325186660021324340881907104863317346496514539057962685610055081066587969981635747363840525714591028970641401109712062804390397595156771577004203378699360072305587631763594218731251471205329281918261861258673215791984148488291644706095752706957220917567116722910981690915280173506712748583222871835209353965725121083579151369882091444210067510334671103141267111369908658516398315019701651511685171437657618351556508849099898599823873455283316355076479185358932261854896321329330898570642046752590709154814165498594616371802709819943099244889575712828905923233260972997120844335732654893823911932597463667305836041428138830320382490375898524374417029132765618093773444030707469211201913020330380197621101100449293215160842444859637669838952286847831235526582131449576857262433441893039686426243410773226978028073189154411010446823252716201052652272111660396665573092547110557853763466820653109896526918620564769312570586356620185581007293606598764861179104533488503461136576867532494416680396265797877185560845529654126654085306143444318586769751456614068007002378776591344017127494704205622305389945613140711270004078547332699390814546646458807972708266830634328587856983052358089330657574067954571637752542021149557615814002501262285941302164715509792592309907965473761255176567513575178296664547791745011299614890304639947132962107340437518957359614589019389713111790429782856475032031986915140287080859904801094121472213179476477726224142548545403321571853061422881375850430633217518297986622371721591607716692547487389866549494501146540628433663937900397692656721463853067360965712091807638327166416274888800786925602902284721040317211860820419000422966171196377921337575114959501566049631862947265473642523081770367515906735023507283540567040386743513622224771589150495309844489333096340878076932599397805419341447377441842631298608099888687413260472

The numner of iterations required for this accuracy is

k
k =
   354

So roughly 500/k digits per iteration

5000/k
ans =
          14.1242937853107

With an error of:

piest - hpf('pi')
ans =
1.5e-5008

A timing test

Time for a multiply in HPF should be roughly inversely quadratic although 35000 digits is not enough to really stress the system

DefaultNumberOfDigits 35000 0
DefaultDecimalBase 1
tic,hpf('pi')*hpf('e');toc

DefaultDecimalBase 2
tic,hpf('pi')*hpf('e');toc

DefaultDecimalBase 3
tic,hpf('pi')*hpf('e');toc

DefaultDecimalBase 4
tic,hpf('pi')*hpf('e');toc

DefaultDecimalBase 5
tic,hpf('pi')*hpf('e');toc

DefaultDecimalBase 6
tic,hpf('pi')*hpf('e');toc
Elapsed time is 0.172152 seconds.
Elapsed time is 0.047454 seconds.
Elapsed time is 0.029139 seconds.
Elapsed time is 0.017130 seconds.
Elapsed time is 0.013764 seconds.
Elapsed time is 0.011370 seconds.

Use, and "Abuse" of HPF

Of course, you can do many interesting things with the HPF toolbox. Above I used it to compute pi to many digits of precision. You can also use this tool to do computations to many digits of precision on numbers that you know inexactly, an abuse of both those numbers and this toolbox. As well, you can also use this toolbox to do computations that are better done using well thought out numerical methods. Good numerical analysis will always trump brute force computation. But, at times brute force can be too much of a temptation.

For example, from a recent Project Euler problem (318), how many leading nines are there in the fractional part of (sqrt(2) + sqrt(3)).^n, where n is a large even number?

Thus, for various values of n...

DefaultNumberOfDigits 2000 3 session
k = sqrt(hpf(2)) + sqrt(hpf(3));
for n = [2 4 8 16 32 64 128 256 512 1024]
  f = fractionalpart(k.^n)
  % How many 9's does that fractional part begin with?
  find(mantissa(f) ~= 9,1,'first') - 1
end
f =
0.89897948556635619639456814941178278393189496131334025686538513450192075491463005307971886620928046963718920245322837824971773091967551468325156790247455710565782549505535314249526021054182354044696262135797338170726488670509120806761761787874917113569314944872260828854054043234840367660016317961567602617940145738798726167431618880160088747737509832902930787829002408945289626663258702188948362702657099008893234345326285099529663624900802313209072918018687172335863967331332533818263813071727532210516312358732472358220589344176709151025767105979664820111738041001283093224823470679882086211598579693467906510557472083659310343660782073560076724633259464660565809954782094852720141025275395093777354012819859118514346569290057761830288514926052059059264741510500684551198309085256259600612934415988485060457568524106813589572009319387995987119508123342717309306912496416512553772738561882612744867017729603144969267446489475909097628876958672740183948202955704657511821263196921566207340190706494528463342837751724748301300887008074945107099482228438478848630615472065501910665157377969567238224074823206389587364928050505545370208871151070507490070079060942464351657980909739718471278024655012658071636590675659963275262312741727316848107263755373846100825378063946268424970487666158993502483170788628126766978234042104205154519286812494254998059478833232684290471974624060020411359975876105520856256400399254793602087572856627545764931713427622502101712870254660313205670077712765246312559134497855929276737253485461336369505958105387736307771786709851971523572468127997170629112036989696702479855018771853745946709763295549768924975409954040003663685761903640800231489959214084134676114890144062685378312358428226011811730352458864310131282191445483167357634359030824540482118739288544372878784039428533406684726021815409729438824599131137810674058013137403287116143491892749760675686621231440687796008888389305280319363353088884557030336164097583650908979240899420484643676028769224352376659283
ans =
     0
f =
0.98979485566356196394568149411782783931894961313340256865385134501920754914630053079718866209280469637189202453228378249717730919675514683251567902474557105657825495055353142495260210541823540446962621357973381707264886705091208067617617878749171135693149448722608288540540432348403676600163179615676026179401457387987261674316188801600887477375098329029307878290024089452896266632587021889483627026570990088932343453262850995296636249008023132090729180186871723358639673313325338182638130717275322105163123587324723582205893441767091510257671059796648201117380410012830932248234706798820862115985796934679065105574720836593103436607820735600767246332594646605658099547820948527201410252753950937773540128198591185143465692900577618302885149260520590592647415105006845511983090852562596006129344159884850604575685241068135895720093193879959871195081233427173093069124964165125537727385618826127448670177296031449692674464894759090976288769586727401839482029557046575118212631969215662073401907064945284633428377517247483013008870080749451070994822284384788486306154720655019106651573779695672382240748232063895873649280505055453702088711510705074900700790609424643516579809097397184712780246550126580716365906756599632752623127417273168481072637553738461008253780639462684249704876661589935024831707886281267669782340421042051545192868124942549980594788332326842904719746240600204113599758761055208562564003992547936020875728566275457649317134276225021017128702546603132056700777127652463125591344978559292767372534854613363695059581053877363077717867098519715235724681279971706291120369896967024798550187718537459467097632955497689249754099540400036636857619036408002314899592140841346761148901440626853783123584282260118117303524588643101312821914454831673576343590308245404821187392885443728787840394285334066847260218154097294388245991311378106740580131374032871161434918927497606756866212314406877960088883893052803193633530888845570303361640975836509089792408994204846436760287692243523766592827
ans =
     1
f =
0.99989585502907246667678642354712825325706208707345172807743181188233981633745201812448888509486024444541840416381068472337630128200438958653654442506596354466898515424607964535500633098706963802336893081391407311958897098938390626526552117418771297928645974815612276972962370143560306815991602336250565581342824022751644082986502556886972782759636244872172072422360766383834129993528145169395448603957028715369658419759397539070352402786266944891459658313428889146687984705883141898536810292981566305986111557822911056177557293174968005251763860071523709503280181257431360327001266284444487366608099598548380346322641986124136787566432088875190140594275367354493755686452955665738204769887191901806932563461936144059637904256606593682744627531017878079446680290670860174342903551134408600675727668715359248417153624677317780569133000236067377117960875862963120774246488182302697283790644960489969677375011082069882097559686390915676299419499285380269238896590564361584837932983134883193386892364637894075980996690253335274869267913446204957492583869709271658003162624191872451854230410175893459593326742261795617629489495434462804693728049097340268677479723615064624821291544924101852464161912404910203858862146764009757066486892770511145118480266369178808870502667343056471077912835813632433507372855564231638669361262121051428901076244369898098289256568030604662535131578820003132776358583410439131272391269697730045821399494994849633079159070052059678612849567106941556676158509941386307951807898810691202508415752109642115838943279981581616350975654932093101018765437227216529796249902768430257918396416671027775568029638773546475901754959203590412046665567984226860160029802451982592592341181431670746111259661491575495745409687023928656547616573504010481671850208049672476364502773485421208358639962738551031501379101534850048107148515054460576852874655221373820622054894765462172888806811874040088710621519174712976086027106865889729440815631977890799656081432074950802508193839865329126097032
ans =
     3
f =
0.99999998915382503050323889952548777431016007928349299950025769422691647221427803134227468084806716490751678091019471385924490980614880992389956948338195591159545107085675469877079013784266430038847367520293009429329944006426795907953431455042002710858650179509083494384678118466066047151365632677930712053796266461286484836397551228712660058027223262596239399508078817575316197857249916535097495195389724979460146529735170153523771553735204847795639125544193586498029145889928509750452433208999670078643178215591961416905129066042786427436584406770658650496300433855921859866158863235967694170972345261548085390008350763961434212880917379575729986232077337849042101321280302418242200456816641150166474361510855260643156671936512541713913552833665318847024151021599394040559897992591383688337075004879503301509104151605329024815068266718955086660330036171885674314779526470499318957772910624688842154856410035007900768108725572323827026032138221345231885062598999937613832504061148422900940485253058917569530219812525309294710504910460001843790316948426460146367517490359282704320398508928999015123379197761520478358135161711850669176727432661259841160306151850527534041414361225987360882682911947777452794333228021687352407144382448015427647517676854922774566611828028235290119049482498626537794159127752194503206838886335820308134098439761539773441566229865969662333419829670080918595117907036538477500971637603899977077950940546176826085390639877034040581543360852827204474012457191328953259444380256926485808051756783596285533374383146680202068238657957955982185728255733119103591566382467336532442392875208701004220591503593261608651118272875136472082783784546311256606163143936854071660024106902504160315269642107910147423814803762960170214338785508645013105697692955118051955631007014442659660922215567004476242132937630161924840041552930458941302439435631425612971099537967784078323007614532931799387827115593996378032280126273182090711698251707458297693910783677605683677250386890268783580000
ans =
     7
f =
0.99999999999999988236048853106193341167413135953211055799592632412563383607346364061925179739314352498810405812666963361076105004918528191485578189068355385920218155413265821498645337591826525207277718041155152768142028312693445470571407492820835594427750642666843295806937980773812563450624192318082153801296808766113085660000443774519337257308599643844084453070493668087154266419169365971217610410325708332727428171352986406267443018109411149943852029053767063400476276493233133118881501599778115359678790326684308685492897372236942038642372708063235406913422693716527781068492770326188365019307005519118316707092723424055748398690909742714079531690095798972544132477038666531082164321052790970105271160684592537388184701798981170737406514200516109179598131614707945780199933415033544352804032406952863591229577070772167639712397442099853946127650056498515117322896737349994967838485132993907997544684492508194197060024792278324575544651152670122219297761046095049970096394876286917037436597811760410157423573101528055605357565254914520845718436040011771217318176271204579238526436440653949394873654165194895645609844216160724924880930764661754053031387981495619005924886795545580673954291788599267958279101195235549565444983870500447749072776265648447853098502104628982752045300333979414076512466185188854420791622267769111477856707228170754446770807077047620899490693647905161956030353403237102538434402686854423706152754510574504932542420015041221448564340025434631199081133937746853463267568971422978050708740237339312835793859646235728699218348124743864612384840919826814881140409245487409780150427649084933792126075978285582480272087528257950276646682192853700185222273934314247709937888053379419677201461227152060141650888514483410033510517827393614384385548542111662153748382404141366890121577336636371621921066596471495936793786731514696714666999302497805849583568019502424141893768288278542238310035746848364132058745604218637621513621426529018859385642927221159969425164531175000000000000
ans =
    15
f =
0.99999999999999999999999999999998616094534134958909462490271337309896749170529389283681232011857365773173114215113629159735473807034486127034443762180671830134592630668304683741275823456281419715364609988647456633424593903570481560864007858450214725649428599652957325037186926397106386935022095975250428615498434945100965846011386549021485930440780629514897955602509154165719215264704625683633345925155501580604949940584127483783904076279170321923927969736473353175148769838703365625885381667918637404524525621111038566168916770081036782065308356566656873358237118066444917033864274748868689434086627619710692826322395700070844483097914094333463455877227426051819402284859423802753700232336057527950292969691848493578394298111271270827911250035391853377965703655281444537512032425785136068004669820389642967105885690280995839457858713772828968204270055022591243968853362880001902699968939082406430186979770159214575709747841264415515351337401316125079706935900945079100660010830175556427313766033870016792337477153431357100768442307220631921427034451969609217557725916233570613093591634062782286745442237389401337140294786397367480090012217059212103390802471658311589216344496788460731757799594808619477044600117375193366933366747189133160918139268406348909361379226013590171266909509970085458867914083293101111576241035872253945772540707239785962025881829011953290651419208994143357293148255741309708170909611258996324332408104511456469559289263242960023246729801045957146989775476302068407418500770950093239554459518991640815678151478640825070235309764270880081085412027162758245015964293303162991886673170479330130255366031784145620481946180384826182792322489982432945565211343210884561799975477937542766356985081764001514517814748611712438779205050797068645337282984155216186896650159866380494024891314185430368850743408816629162291580659928327660439783916566526697301388849702343944505624532790865864947916912617481750499881478470425270364825086640139486292852441716520000000000000000000000000000
ans =
    31
f =
0.99999999999999999999999999999999999999999999999999999999999999980848056615488635889628649097077479455946535727738867217297155625795968871594298715887120327404991887543483760619505603863491417774183468618992097394596608689187530964855869191160724798478841477300879446881443946853812262248797454016468040344012945732719627763103890494497151233158788154035455623776685598770849322773754523545926672332710733914961477164038667698602796940373566469602724000391452585143574622594556692546830448882536919930795196383623469516056843994853208000276108519583657895593325232582180773296991657640885258956950882573207388926337034062009683102829830758278264939430874761527757965143132422258789383585109813139650403324350567923155942301830455912543386688609083559719262428716698721165839012623050179352345126206686641489998334064671240691357030907741626201189843574068247343525834853803303941969159254028068185302194668319054655092341799610756911110633873422030404077745765640388563315447623751880779491203734944432872760792020457058072064159482456200806960735467706441213274624585430907154898272866158992730228702954954881027724195213112635799173408617034141749947718470998329055438218978493419662234865067836251116926858024016550927682757407098712088269963278065456263726956949356971109761472562965876149330651954778244751302745622516748531633575978045911462683430142100795911718342826452062695997496692198216259302902250487391347290720849455055207416544239962143709705558827061998765572996287215564630811307870496356215768713761080034888800751670724771642038921375171599787216085329138820036470396129446802290306565686780337789672925210030901796806741709049534354043401723663283317596071427185362558413651832932623447261879086280892047874459975238604118999531668892929225309036287812723059975838044297573846653209792196379457076687292338904260685114532345510255472777316632831030722467544532075045116850961167286999279723095922782251309437025634270607000000000000000000000000000000000000000000000000000000000000
ans =
    63
f =
0.99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999996332030645964713955628552273298853296553431050501414441867876628512670545207724373843575842980309882532672819946812967268623279308788693344158295895048722544793389256141142103140926289957532186520859024287943837590906009971081992748371597448538547800702995381132056748966814478357203941102053091277059272329932524970561243588195739123671149186122466138092238839720984249536730303395717749271840383949288018758390917417275441647977214364019244669494380595170635329792710165522888177118448328731837368027312174169396858784433794602928172278029364426449564870137792974347491590873461241631617936833017118916418893866182886859621159694007471954201814734461754427599986203518005613858249125372992297680317843588778052739895318412330505974283887707671901923486816978654984031706162293740438597614385161698737032364058820166710024872364220159011843356048083588523473524009319246077681599835113391612563142237029435553702249763107454090953396572320454743552808278237706042537122541013554068719751659537390859079886696331846815042458318919074439856366959037594134111052871314002453895068807788010689163814154801622449645504718589438477021859240719483246936074356876736576047897264924215758872621717868366584252228705008480621948223074317400854790363012559934789275131279156579466977642224744700981089541260445139565161682246787790044520568295544968004629959639032970041159202859949760223859618608635745031962525714257099504250626667649248825540020361662478811271453481883775594657788877366401887453324604376521844403726897916366400411892808358433622882237819320033200451501353530887178563084239304638031315793833842458008151289725305792663096294688281808694882887456549998008782113154786623538873060845882890294600133793665686843581716702529693386721921809910000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ans =
   127
f =
0.99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999865460008178579664252420459867670689724055911450544380719798347476496992008664752005729381996257583742602177320183502573330356169935914102109004257968799124504933678417081037469425883684494640146984499197931231593247766779389849982309032734204446415573731854430642986778931658019598907109622526094986833916377893741347636991126524534948968929599098302268973549613906575905648580990696446122840698325435868729868507284926464910028906720512403452085334407551495435360380837116754629161026312161808558352617713811494842216998814698743183461955111964820081195088505022231492883780474612887317744106986332342765609029634147705788393433454925251776885829864423212690000538371076910712192019143823911721549188024342079024905972205098464081613747652634998711476654586851603669974757375832580443929821656346372962080149042354318777674725262607886456292712721703891153674063425495719889571026245982570150881667698773445570712594145254946428744352084041254754674778718204177945788752045975232517174452241420736324789019070909783780092947838304271574534362728517385315884117218614598033054590101413799558190932932120280562219787645712674917859701088015043739418216614259490964147571561448135618355817145150320376204612760156246995702727615285494362678236976207835947971025130491355702429118215571165215648803700877924274832134283600086276251157165997194546461936679529560027519413768657708558713941777668187279060951008399195890755316746668032604268788323893650496459592989006585683283506032305357504131994000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ans =
   254
f =
0.999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999998189899060069214916787597281795825342471360804127123471243133274390447549330835196138177069135073495274759354411216182002246126143348902330815774326992894512867324244958256995059408826909133191962459013304741424912176141862644338294702626226769280323614288370149239413498082662371747302079097157269392729390547581055095201952952088899699401216370294398940536135805097607377145391384478839850001135184430326093830448919804478889908259022763394782769350273245736239785279602874902815219510165062827256520985693939328911909732400245269822286847532683777400705690219197060923365805795203377160359474879975256914307776406559238424730363091500350822097520610186962173660207036442466264632908522651690100437759251567316398286241822560697405944639148843498102574826464108270603355663028924673569443561820887264202336089028066934851755322486335413828302612548701658161953737519972052722141881327939641113676511864182664614771208966185961774651235284595117547315046065614293662056544721749791275
ans =
   509

The problem is brute force will fail you in this quest, unless you find the key. That, of course, is the essence of all Project Euler problems.

Contact us