FAQ
Here's the problem most easily explained:

http://play.golang.org/p/PNbcWeTxrx

I know I can just stringify the float and parse before and after the "."
but... yeah wondering if there's some sort of known precision-trick I'm not
aware of, or maybe just maybe even some sort of tiny bug in math.Modf()?
(Doubt it but...)

--

Search Discussions

  • Jan Mercl at Jan 24, 2013 at 9:29 am

    On Thu, Jan 24, 2013 at 10:13 AM, Philipp Schumann wrote:
    Here's the problem most easily explained:

    http://play.golang.org/p/PNbcWeTxrx

    I know I can just stringify the float and parse before and after the "."
    but... yeah wondering if there's some sort of known precision-trick I'm not
    aware of, or maybe just maybe even some sort of tiny bug in math.Modf()?
    From the link

    f := 4.3;

    // the problem: how to get at 0.3 in f?

    It's more or less the same as

    s := "4.2999999999999998"

    // the problem: how to get at ".3" in s?

    A: It's not there: http://play.golang.org/p/MDlErCa7yc

    -j

    --
  • David DENG at Jan 24, 2013 at 9:29 am
    The fractional part you got is inaccurate. That's a small inevitable error.
    A simple way to got an "0.3" text out of the value near it is to limit the
    number of digits for fractional part. i.e. use %.10v instead of %v.

    http://play.golang.org/p/cTbc068Ls4

    David
    On Thursday, January 24, 2013 5:13:04 PM UTC+8, Philipp Schumann wrote:

    Here's the problem most easily explained:

    http://play.golang.org/p/PNbcWeTxrx

    I know I can just stringify the float and parse before and after the "."
    but... yeah wondering if there's some sort of known precision-trick I'm not
    aware of, or maybe just maybe even some sort of tiny bug in math.Modf()?
    (Doubt it but...)
    --
  • Roger peppe at Jan 24, 2013 at 9:49 am
    Why do you care about the exact value?

    You can print it out to any degree of precision you like:
    http://play.golang.org/p/g4RO7GrbXP

    The actual value stored in the float value is not
    .3 exactly, because that's not exactly representable.

    On 24 January 2013 09:13, Philipp Schumann wrote:
    Here's the problem most easily explained:

    http://play.golang.org/p/PNbcWeTxrx

    I know I can just stringify the float and parse before and after the "."
    but... yeah wondering if there's some sort of known precision-trick I'm not
    aware of, or maybe just maybe even some sort of tiny bug in math.Modf()?
    (Doubt it but...)

    --
    --
  • Michael Jones at Jan 24, 2013 at 1:37 pm
    and this instructive version...
    http://play.golang.org/p/oOQB8CQF26
    On Thu, Jan 24, 2013 at 1:49 AM, roger peppe wrote:

    Why do you care about the exact value?

    You can print it out to any degree of precision you like:
    http://play.golang.org/p/g4RO7GrbXP

    The actual value stored in the float value is not
    .3 exactly, because that's not exactly representable.

    On 24 January 2013 09:13, Philipp Schumann wrote:
    Here's the problem most easily explained:

    http://play.golang.org/p/PNbcWeTxrx

    I know I can just stringify the float and parse before and after the "."
    but... yeah wondering if there's some sort of known precision-trick I'm not
    aware of, or maybe just maybe even some sort of tiny bug in math.Modf()?
    (Doubt it but...)

    --
    --


    --
    Michael T. Jones | Chief Technology Advocate | mtj@google.com | +1
    650-335-5765

    --
  • Itmitica at Jan 24, 2013 at 3:31 pm
  • Itmitica at Jan 24, 2013 at 3:45 pm
    ... an even more obvious "who needs math?"

    http://play.golang.org/p/2qOR06AJqc

    --
  • John Nagle at Jan 24, 2013 at 6:26 pm

    On 1/24/2013 1:13 AM, Philipp Schumann wrote:
    Here's the problem most easily explained:

    http://play.golang.org/p/PNbcWeTxrx

    I know I can just stringify the float and parse before and after the "."
    but... yeah wondering if there's some sort of known precision-trick I'm not
    aware of, or maybe just maybe even some sort of tiny bug in math.Modf()?
    (Doubt it but...)
    math.SmallestNonzeroFloat64 is far smaller than 0.0000000000000001.
    This is floating point. math.SmallestNonzeroFloat64 is around 5e-324.
    You can add math.SmallestNonzeroFloat64 to a number near 1 and
    get back the same number you started with.

    http://play.golang.org/p/ugEi4eZhmC



    --
  • Itmitica at Jan 24, 2013 at 8:34 pm
    How about this? This time with math: http://play.golang.org/p/PoA5fz8AO4

    Though, again, no math is needed: http://play.golang.org/p/J34C3-P3zo

    The pattern here is that mixing variables with literals: e.g. g := f - 4,
    results in longer precision.
    So, add and subtract to the fractional part you want to test against, the
    integer part: fint. It makes perfect sense, no?
    This will lead to the same longer precision for the test value also, as for
    the deducted frac value.

    --
  • Itmitica at Jan 24, 2013 at 8:37 pm

    On Thursday, January 24, 2013 10:33:58 PM UTC+2, itmi...@gmail.com wrote:
    Though, again, no math is needed: http://play.golang.org/p/J34C3-P3zo
    This example is also interesting with regards to the parenthesized
    evaluation: http://play.golang.org/p/se8AQiIz48

    --
  • Bryanturley at Jan 24, 2013 at 8:42 pm
    http://en.wikipedia.org/wiki/Double-precision_floating-point_format#IEEE_754_double-precision_binary_floating-point_format:_binary64

    Using unsafe you could extract the exponent and create a bitmask for the
    would-be integer bits and zero them.
    Knowing the exponent and fractional parts you could make a decent guess at
    how many decimal digits it would be.
    I would show you but play.golang.org only plays it safe ;)

    I wonder if it would be faster than those conversions...
    On Thursday, January 24, 2013 2:33:58 PM UTC-6, itmi...@gmail.com wrote:

    How about this? This time with math: http://play.golang.org/p/PoA5fz8AO4

    Though, again, no math is needed: http://play.golang.org/p/J34C3-P3zo

    The pattern here is that mixing variables with literals: e.g. g := f - 4,
    results in longer precision.
    So, add and subtract to the fractional part you want to test against, the
    integer part: fint. It makes perfect sense, no?
    This will lead to the same longer precision for the test value also, as
    for the deducted frac value.
    --
  • Matt Kane's Brain at Jan 24, 2013 at 8:49 pm
    unsafe isn't needed. http://golang.org/pkg/math/#Float64bits
    On Thu, Jan 24, 2013 at 3:42 PM, bryanturley wrote:
    http://en.wikipedia.org/wiki/Double-precision_floating-point_format#IEEE_754_double-precision_binary_floating-point_format:_binary64

    Using unsafe you could extract the exponent and create a bitmask for the
    would-be integer bits and zero them.
    Knowing the exponent and fractional parts you could make a decent guess at
    how many decimal digits it would be.
    I would show you but play.golang.org only plays it safe ;)

    I wonder if it would be faster than those conversions...

    On Thursday, January 24, 2013 2:33:58 PM UTC-6, itmi...@gmail.com wrote:

    How about this? This time with math: http://play.golang.org/p/PoA5fz8AO4

    Though, again, no math is needed: http://play.golang.org/p/J34C3-P3zo

    The pattern here is that mixing variables with literals: e.g. g := f - 4,
    results in longer precision.
    So, add and subtract to the fractional part you want to test against, the
    integer part: fint. It makes perfect sense, no?
    This will lead to the same longer precision for the test value also, as
    for the deducted frac value.
    --


    --
    matt kane's brain
    http://hydrogenproject.com

    --
  • Bryanturley at Jan 24, 2013 at 9:06 pm

    On Thursday, January 24, 2013 2:48:44 PM UTC-6, mkb wrote:
    unsafe isn't needed. http://golang.org/pkg/math/#Float64bits
    Ooooh sexy

    Now that I take the time to look at this in more detail, my example would
    have looked a lot like

    http://golang.org/src/pkg/math/modf.go

    So nevermind ;)

    On a semi-unrelated note this code has just revealed this headache inducing
    code
    http://play.golang.org/p/efD29937Jh


    --
  • Matt Kane's Brain at Jan 24, 2013 at 9:10 pm
    "int" is not a keyword!
    http://golang.org/ref/spec#Keywords
    On Thu, Jan 24, 2013 at 4:06 PM, bryanturley wrote:
    On Thursday, January 24, 2013 2:48:44 PM UTC-6, mkb wrote:

    unsafe isn't needed. http://golang.org/pkg/math/#Float64bits
    Ooooh sexy

    Now that I take the time to look at this in more detail, my example would
    have looked a lot like

    http://golang.org/src/pkg/math/modf.go

    So nevermind ;)

    On a semi-unrelated note this code has just revealed this headache inducing
    code
    http://play.golang.org/p/efD29937Jh


    --


    --
    matt kane's brain
    http://hydrogenproject.com

    --
  • Bryanturley at Jan 24, 2013 at 9:29 pm

    On Thursday, January 24, 2013 3:10:22 PM UTC-6, mkb wrote:
    "int" is not a keyword!
    http://golang.org/ref/spec#Keywords
    But
    http://play.golang.org/p/2K_lBPVoGN

    and worse
    http://play.golang.org/p/rg4Lz-LY31

    go has no operator overloading or method overloading (yay), but it does
    have conversion almost overloading O.o

    perhaps they should be on a reserved non-keyword list?

    --
  • Bryanturley at Jan 24, 2013 at 9:32 pm

    On Thursday, January 24, 2013 3:29:02 PM UTC-6, bryanturley wrote:

    On Thursday, January 24, 2013 3:10:22 PM UTC-6, mkb wrote:

    "int" is not a keyword!
    http://golang.org/ref/spec#Keywords
    But
    http://play.golang.org/p/2K_lBPVoGN

    and worse
    http://play.golang.org/p/rg4Lz-LY31
    Look I gave someone else a headache!
    http://play.golang.org/p/GnvdE-otbV

    go has no operator overloading or method overloading (yay), but it does
    have conversion almost overloading O.o

    perhaps they should be on a reserved non-keyword list?
    --
  • Itmitica at Jan 24, 2013 at 9:54 pm
  • Itmitica at Jan 24, 2013 at 9:57 pm
    Shadowing anyone?

    --
  • Bryanturley at Jan 24, 2013 at 9:58 pm

    On Thursday, January 24, 2013 3:56:57 PM UTC-6, itmi...@gmail.com wrote:
    Shadowing anyone?
    Well shadowing has never bothered me, but this is a type name that is being
    redefined.


    --
  • Charlie Dorian at Jan 25, 2013 at 1:14 am
    Rather than a rather arbitrary epsilon64, use math.Nextafter. [Usually
    math.Nextafter(1.0, Inf) is used for epsilon.]
  • Philipp Schumann at Jan 25, 2013 at 5:56 am
    Most above approaches reformulate %v but the following should illustrate
    much more clearly what the actual problem/use-case is:

    http://play.golang.org/p/G8fsx7yhBN

    On Friday, January 25, 2013 8:14:03 AM UTC+7, Charlie Dorian wrote:

    Rather than a rather arbitrary epsilon64, use math.Nextafter. [Usually
    math.Nextafter(1.0, Inf) is used for epsilon.]
    --
  • Itmitica at Jan 25, 2013 at 5:31 pm

    On Friday, January 25, 2013 7:56:49 AM UTC+2, Philipp Schumann wrote:
    the following should illustrate much more clearly what the actual
    problem/use-case is

    I don't see any problem ;)
    http://play.golang.org/p/9v4W1-hmXN

    But I do see how different use cases may look like problems.
    Somebody already told you: why do you care so much about the exact value,
    the precision is yours to command.

    Mitică

    --
  • Philipp Schumann at Jan 25, 2013 at 6:38 pm
    Haha, OK I guess this is the work-around I'll be using.

    Imagine your program sits between two external libs/APIs you have no
    control over. One expects a version number as two ints (major, minor), the
    other provides one but as float (as in my example). Bam, there's a use-case
    where I have very little room for any refactoring.

    Now, your solution mindblowingly works. Instead of multiply-by-10, just multiply
    by 100 then divide by 10... neat-o. Utilizing float precision issues
    themselves to combat float precision issues, so to speak. Didn't even occur
    to me it could ever work this way, all I'm painfully aware of is slowly
    ever-accumulating float error, not self-correcting float error ;)) I
    better make DAMN sure I comment in the code why I'm doing this, otherwise
    some smart-ass (such as: me, 1 or 10 months later) comes along, reads the
    code and thinks "hey I can streamline this, just multiply by 10 instead".

    Nasty edge-cases... don't we love them... anyway, thanks for the brain
    kickstarter ;)

    On Saturday, January 26, 2013 12:31:16 AM UTC+7, itmi...@gmail.com wrote:
    On Friday, January 25, 2013 7:56:49 AM UTC+2, Philipp Schumann wrote:

    the following should illustrate much more clearly what the actual
    problem/use-case is

    I don't see any problem ;)
    http://play.golang.org/p/9v4W1-hmXN

    But I do see how different use cases may look like problems.
    Somebody already told you: why do you care so much about the exact value,
    the precision is yours to command.

    Mitică
    --
  • Itmitica at Jan 25, 2013 at 6:44 pm

    On Friday, January 25, 2013 8:30:22 PM UTC+2, Philipp Schumann wrote:
    Now, your solution mindblowingly works. Instead of multiply-by-10, just multiply
    by 100 then divide by 10... neat-o.
    I believe you've overlooked the math.Ceil() calls inbetween? :)
    Also, http://play.golang.org/p/_kMYWFgaHM

    That is to say, it doesn't matter how it looks(%v), it matters what
    (common) precision you decide for.
    Mitică

    --
  • Itmitica at Jan 25, 2013 at 6:56 pm

    On Friday, January 25, 2013 8:44:30 PM UTC+2, itmi...@gmail.com wrote:
    Also, http://play.golang.org/p/_kMYWFgaHM
    Actually, scratch that: http://play.golang.org/p/uM79NkMX1o

    Mitică

    --
  • Bryanturley at Jan 25, 2013 at 7:03 pm

    On Friday, January 25, 2013 12:30:22 PM UTC-6, Philipp Schumann wrote:
    Haha, OK I guess this is the work-around I'll be using.

    Imagine your program sits between two external libs/APIs you have no
    control over. One expects a version number as two ints (major, minor), the
    other provides one but as float (as in my example). Bam, there's a use-case
    where I have very little room for any refactoring.
    A library that deals with exact float values? Sounds like something I
    would try to avoid.
    floats are more stable now but in the past they have been awkwardly
    unstable between archs.
  • Alexander Usov at Jan 25, 2013 at 2:05 pm
    Just to be precise -- SmallestNonzeroFloat64 has nothing to do with
    epsilon64 (which isn't exposed in the math for some reason).


    On Friday, 25 January 2013 01:14:03 UTC, Charlie Dorian wrote:

    Rather than a rather arbitrary epsilon64, use math.Nextafter. [Usually
    math.Nextafter(1.0, Inf) is used for epsilon.]
    --

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedJan 24, '13 at 9:13a
activeJan 25, '13 at 7:03p
posts27
users11
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase