Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

BrowserUK did a good job of explaining the real issue, which you now get, but I wanted to further clarify a tangential point:

... for literal floating point values you would in general have to write them in a number base of a power of two if you want to express ... them exactly.

It's one of the mathematical niceties of binary that any binary floating point can be exactly represented in decimal. It comes about because 2 (binary) is a factor of 10 (decimal: 2*5)

x = c * (2**p) # the value you want to express c # the coefficient p = -n # the smallest power of two that goes into x; # negative, since it's a binary fraction x = c*(2**p) = c*(2**-n) = ... [ 1 ] [ 1 ] [ 5**n ] [ 5**n ] = ... = c*[------] = c*[------]*[------] = c*[-------] = ... [ 2**n ] [ 2**n ] [ 5**n ] [ 10**n ] = ... = c * (5**n) * (10**-n) = c * (5**n) ** (10**p) k = c * (5**n) # k integer, so exactly representable in decimal x = k * (10**-n) # since n is finite and k is an integer, # x is exactly representable in decimal

As might be obvious from the final statement, an n-digit binary fixed point can be expressed exactly in an n-digit decimal fixed point.

It turns out, there's something else interesting you can tell about the number of digits for an exact power of two: specifically, which digit d (after the decimal point) that the decimal expansion will start on

x c*(2**-n) binary decimal d log10(x) 1/2 1*(2**-1) 0b0.1 0.5 1 -0.301029996 1/4 1*(2**-2) 0b0.01 0.25 1 -0.602059991 3/4 3*(2**-2) 0b0.11 0.75 1 -0.124938737 1/8 1*(2**-3) 0b0.001 0.125 1 -0.903089987 7/8 7*(2**-3) 0b0.111 0.875 1 -0.057991947 1/16 1*(2**-4) 0b0.0001 0.0625 2 -1.204119983 15/16 15*(2**-4) 0b0.1111 0.9375 1 -0.028028724 1/32 1*(2**-5) 0b0.00001 0.03125 2 -1.505149978 1/64 1*(2**-6) 0b0.000001 0.015625 2 -1.806179974 1/128 1*(2**-7) 0b0.0000001 0.0078125 3 -2.107209970 3/128 3*(2**-7) 0b0.0000011 0.0234375 2 -1.630088715 5/128 5*(2**-7) 0b0.0000101 0.0390625 2 -1.408239965 9/128 9*(2**-7) 0b0.0001001 0.0703125 2 -1.152967460 13/128 13*(2**-7) 0b0.0001101 0.1015625 1 -0.993266617

You might see that d = -floor(log10(x)) = ceil(-log10(x)). In general, for a given x = c*(2**-n) < 1, the decimal expression will start on the dth digit after the decimal point, and end on the nth digit after the decimal point; thus, the length of the decimal expansion (ignoring leading and trailing zeroes) is L = n - d + 1.

For example, the smallest representable 52bit fraction x = 2**-52 = 2.2204...e-16: it will start on the 16th digit (log10(x)=-15.654 -> d=16) and run to the 52nd digit. Double precision floating-point numbers (the common native floating-point in perl5) use a 52bit fractional component, with the encoding usually meaning one plus the fractional part times some power of two (x = (1+f)*(2**p)). So, that (1+f) can be exactly expressed in decimal as

1.0000 0000 0000 000f ffff ffff ffff ffff ffff ffff ffff ffff ffff ^1 16^ 52^ + ^ points to the nth digit after decimal point

And thus, you need the 16 digits after the decimal point to indicate the last bit of accuracy in the underlying binary fraction, as BrowserUK said. (But you would need all 52 decimal digits after the decimal point to exactly represent the full value.)

Sorry, I like stuff like this: all this to say: you can exactly represent any n-digit binary fraction within n decimal digits after the decimal point.


In reply to Re^5: Variables are automatically rounded off in perl (humans) by pryrt
in thread Variables are automatically rounded off in perl by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (4)
As of 2024-04-19 05:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found