Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Re^4: Variables are automatically rounded off in perl (humans)

by hexcoder (Curate)
on Jul 22, 2016 at 07:53 UTC ( [id://1168309]=note: print w/replies, xml ) Need Help??


in reply to Re^3: Variables are automatically rounded off in perl (humans)
in thread Variables are automatically rounded off in perl

To me the sane thing is to have print() deliver a value that, when assigned back to a scalar, will result in the same value.

I think the following is rather pathetic:

C:\>perl -le "print sqrt(3);" 1.73205080756888 C:\>perl -le "print 'WTF' if 1.73205080756888 != sqrt(3);" WTF

That should be expected for integer values, but 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 (and match) them exactly. In that sense print() cannot be of use to do the sane thing because information is already lost due to conversion to base ten (see commensurability).

Replies are listed 'Best First'.
Re^5: Variables are automatically rounded off in perl (humans)
by BrowserUk (Patriarch) on Jul 22, 2016 at 08:04 UTC
    but 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 (and match) them exactly

    You've missed the point.

    It is not about representing root3 exactly; it is about displaying and printing the calculated internal value of root3 such that it retains all the available accuracy, so that that same level of accuracy may be restored from the printed value.

    This is always possible; but perl does not achieve it.

    The point is about reproducibility.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
    In the absence of evidence, opinion is indistinguishable from prejudice.
      This is always possible...

      I agree (now). Sorry, that was my fault. Decimal values like 0.2 cannot be represented exactly with finite precision in number base two, but it works certainly the other way round since all fractions of powers of two don't have repeating decimals.

Re^5: Variables are automatically rounded off in perl (humans)
by pryrt (Abbot) on Jul 22, 2016 at 14:14 UTC

    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.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1168309]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (2)
As of 2024-04-25 20:03 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found