Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. The Lounge
  3. An annoying JavaScript quirk

An annoying JavaScript quirk

Scheduled Pinned Locked Moved The Lounge
javascript
35 Posts 20 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Stefan_Lang

    Actually there is a rather short explanation by analogy: 0.3 cannot be represented exactly in binary for the same reasons that 1/3 cannot be represented in decimal - you'd need an endless number of digits.

    L Offline
    L Offline
    lewax00
    wrote on last edited by
    #26

    Except you did just represent it exactly in decimal: 1/3. There's also the 0.3 with a bar over the three. IEEE floating point does not support such notations though.

    T 1 Reply Last reply
    0
    • L lewax00

      Except you did just represent it exactly in decimal: 1/3. There's also the 0.3 with a bar over the three. IEEE floating point does not support such notations though.

      T Offline
      T Offline
      thomas michaud
      wrote on last edited by
      #27

      You are confusing 1/3 with 3/10th. The two are not the same. Actually the problem is 1/10th - which can't be accurately represented in binary floating point. (It can be represented in base_10 floating point - but base_10 floating point isn't perfect either. It can't represent 1/3.) The result is a rounding error on addition (1/10 + 1/10 + 1/10). Be very wary of doing financial calculations in base_2 floating point. It ALWAYS bites you eventually.

      L 1 Reply Last reply
      0
      • T thomas michaud

        Except that Javascript isn't always run on the client. There is server-side javascript.

        Z Offline
        Z Offline
        ZurdoDev
        wrote on last edited by
        #28

        True.

        There are only 10 types of people in the world, those who understand binary and those who don't.

        1 Reply Last reply
        0
        • Z ZurdoDev

          So, curiosity got the better of me. Pleas explain. Javascript is uncompiled source code on the client. That means it can all be hacked, and somewhat easily too. Nothing critical of nature should be left to JS alone. Always validate server side. What part do you disagree with?

          There are only 10 types of people in the world, those who understand binary and those who don't.

          T Offline
          T Offline
          thomas michaud
          wrote on last edited by
          #29

          Except that Javascript isn't always run on the client. There is server-side javascript.

          Z 1 Reply Last reply
          0
          • T thomas michaud

            You are confusing 1/3 with 3/10th. The two are not the same. Actually the problem is 1/10th - which can't be accurately represented in binary floating point. (It can be represented in base_10 floating point - but base_10 floating point isn't perfect either. It can't represent 1/3.) The result is a rounding error on addition (1/10 + 1/10 + 1/10). Be very wary of doing financial calculations in base_2 floating point. It ALWAYS bites you eventually.

            L Offline
            L Offline
            lewax00
            wrote on last edited by
            #30

            thomas.michaud wrote:

            You are confusing 1/3 with 3/10th. The two are not the same.

            It was an example of a number that couldn't be represented in a similar base 10 system, there's no confusion.

            1 Reply Last reply
            0
            • Z ZurdoDev

              So, curiosity got the better of me. Pleas explain. Javascript is uncompiled source code on the client. That means it can all be hacked, and somewhat easily too. Nothing critical of nature should be left to JS alone. Always validate server side. What part do you disagree with?

              There are only 10 types of people in the world, those who understand binary and those who don't.

              C Offline
              C Offline
              Chris Maunder
              wrote on last edited by
              #31

              I was making a joke about how ubiquitous Javascript has become. From node.js to compiled JAvascript/HTML5 in Windows applications. Your statement that nothing important should be left to Javascript is now, unfortunately, ironic. It worries me. Not because I think there's anything inherently insecure about server side (or compiled) Javascript, it's just that, well, there are much, much better languages that guide (or even constrain) you into writing better, more maintainable and more efficient code.

              cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP

              1 Reply Last reply
              0
              • J Jon Woo

                .30000000000000004 ? why does that happen?

                B Offline
                B Offline
                BrainiacV
                wrote on last edited by
                #32

                It's called floating point error. Ever look at floating point numbers in binary? Probably not, you young whippersnappers have never had to poke your noses behind the curtain. Just like decimals have certain precision problems (like 1/3), binary has the same problem, but for different numbers. 0.1 in floating point binary is a repeating value like 1/3 is. Modern calculators now have two extra guard digits that are used to round the values, so 1/3 *3 = 1 instead of 0.99999999... It depends on the math package as to how many digits are used versus reported. 0.1 = .0001000110011001100110011 (repeat the 0011 forever) in binary floating point.

                Psychosis at 10 Film at 11 Those who do not remember the past, are doomed to repeat it. Those who do not remember the past, cannot build upon it.

                1 Reply Last reply
                0
                • R Reelix

                  var j = 0; j += 0.1; j += 0.1; alert(j); // Alerts 0.2 j += 0.1; alert(j); // Take a guess

                  -= Reelix =-

                  J Offline
                  J Offline
                  Jasmine2501
                  wrote on last edited by
                  #33

                  Yup, this is why you always format floating point numbers before displaying them.

                  1 Reply Last reply
                  0
                  • D David Crow

                    So what exactly is the precision-related quirk? I also notice that 0.8 and 0.9 exhibit the same behavior. Can you get around it by using toFixed()?

                    "One man's wage rise is another man's price increase." - Harold Wilson

                    "Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons

                    "Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous

                    M Offline
                    M Offline
                    Moshe Katz
                    wrote on last edited by
                    #34

                    Forget just 0.3, 0.8, and 0.9. It actually happens more often that it doesn't. I wrote a quick script that runs from 1 to 100 in 0.1 increments and more of them are wrong than right. See http://jsfiddle.net/txa9M/[^] UPDATE: Yes, you can get around it using toFixed(1). See http://jsfiddle.net/txa9M/1/[^]

                    1 Reply Last reply
                    0
                    • B Brisingr Aerowing

                      0.30000000000000000004 :doh: (Chrome & Firefox)

                      Gryphons Are Awesome! ‮Gryphons Are Awesome!‬

                      K Offline
                      K Offline
                      KP Lee
                      wrote on last edited by
                      #35

                      .30000000000000000004 is an 19 place accurate, 20 place number. real is 6 place, double is 12, a native 64 bit real would be 19 place. You're getting the most accurate version of the out of the box "real" numbers. To keep your "most" accurate answer, add 1 and when you render the result, it would be "result/10."

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups