9
coder-guy
45d

Piddling, and trying to learn some game stuff. Very simple game stuff.
Example code:

if (level % 10 === 0...) {
speed += 0.3;
...
} else if (level % 5 === 0...) {
speed += 0.1;
...
}

But because Javascript, console log reads:
speed: 0.5 <-- this is the initial console log
speed: 0.6
speed: 0.8999999999999999
speed: 0.9999999999999999

Well done Javascript, well done.

Comments
  • 16
    That's just how IEEE 754 floating points work
  • 11
    I hate js as much as the next guy, but this is really much more to do with floating point precision than it is js as a language.
  • 7
    Actually, that's how all binary decimals work

    Try expressing 1/3 as a rational base 10 number...
    Base 2 just struggles with other values like 0.3
  • 5
    Either use integers and regularly use parseInt to reset any decimsls or accept it

    The standard for float and double has this quirk but its also mich much faster than for example the c# decimal type which handles 0.1 or 0.3 fine.

    But decimal has the same problem with 1/3 == 0.33333333333...

    So any way you go, as soon as you start using decimals just accept that you will have lots of them, in any language :)
  • 11
    When you add two floating points, you're basically asking the mantissa to have a fight to the death. The odds of either coming out completely whole are low. 😮
  • 0
    Look up fuzzy comparisons for float values.

    It will show you how to deal with this.
  • 3
    @Demolishun Instead I'd rather use something as trivial as integers.

    Floats are avoidable. And should be avoided if there is no "Decimal" type.

    https://w3schools.com/jsref/...

    toFixed converts to string, which is another perversion imho.

    Just use a bit of brain and integers.

    Fast, simple and no magic.
  • 1
    @IntrusionCM floats are unavoidable in game programming. They are also hardware accelerated like integers. Reinventing the float wheel could be expensive. I say unavoidable because at some point you will use gpu for something. It uses floats all over the place and is accelerated. Maybe if you use a high enough abstraction, but even with a very abstracted engine like Godot, you still use floats for gpu stuff. Especially in shaders. I don't think you can write a shader without floats. So trying to avoid floats because of value uncertainty will most likely have a performance penalty.
  • 3
    One could say it's a "flop"
    Hahahahahahaha kill me.
  • 1
    @Demolishun I think you missed the part of decimals.

    This is about JavaScript afaik.

    I "guessed" vanilla JavaScript.

    I somehow hope that vanilla JS without specific libraries cannot do GPU rendering or HW accel...

    Godot is C I think... Or C++. That cannot be compared to JS.

    I get your point, but I was specific on JS, not general.
  • 0
    @IntrusionCM Javascript is JIT compiled (at least V8 is). I cannot imagine they are not using assembly language instructions that accelerate floats. It would be dumb not to.
  • 1
  • 1
    @Demolishun I might be completely wrong as JS is way out of my knowledge, especially deeper JS / Compiler vodoo dodoo and so on...

    http://jayconrod.com/posts/52/...

    But afaik integers are fastest in JS.
  • 1
    @SortOfTested And that would be compiled to processor instructions that accelerate floats. We have had floating point support in CPUs since the 486.
  • 0
    @IntrusionCM Yes, they are most likely to be faster. But not for float like operations. Back in the day they used to use fixed point math because it was faster. Now with hardware support in instructions sets they just use floats. Fixed point had the same representation issues as floating point did.
  • 1
    @Demolishun
    That's the implementation, no need to guess.
  • 5
    Tip:

    Use integers wherever possible in games (especially for stats); it will save you a very large number of headaches. Geometry is far less likely to have gaps if the coordinates are always ints, for example, and you won’t run into multiplied rounding errors in stats or difficulty scaling either. Nor will you need to worry about rounding data prior to displaying it to the player — or players complaining when their math yields different results than yours. Checking your game math (and looking for invalid client data, e.g. hackers) is also significantly less problematic when everything is nice and clean. Example: Starcraft unit stats and game replays.

    Floats are acceptable for animations, tweens, interactions, etc. — anywhere that rounding errors are not noticeable and certainly are not revealed.

    But @Root, what about vectors and trig? I need floats for my movement system! That is trickier, but the short is that floats work well here, but you should only use ints for verification. Your coordinates should still be integers. Something in your game world can probably move more slowly than one unit per tick, so you’ll need to use floats for tweening. For recording and replay, player movement stored in integer degrees and magnitudes is the way to go; you simply tween the rest for animations — and on the server for verification and truth.

    Example: a player can rotate their spacecraft `theta` degrees per second, and can thrust `dV` Newtons per second. You send the durations (in ms) to the server whenever the player moves; it knows rotation and thrust values. Doing the calculations on these generates the `dX` and `dY` floats for movement and graphics tweening. The server also does this math and sends updates (x,y,dx,dy,theta) to ensure the client can’t cheat, and is in the same place for all players.

    tl;dr
    Integers are your truth, and truth prevents headaches. Floats are for graphics; think very carefully before using them elsewhere.
  • 0
    @IntrusionCM integers are always faster because of how they work in computers.
  • 0
    @IntrusionCM no since js really doesnot have integers ;)

    It only has Number which is an IEEE double

    https://developer.mozilla.org/en-US...

    So no integers is not faster in any way in js as you would have to discard decimals over and over.
  • 3
    bEcAuSe JAvASCrIpT
  • 1
    @Voxera Did you read the V8 article?

    They use integers whenever possible.

    And if V8 does it, I think others will do it, too.
  • 2
    *laughs in fixed point*
  • 0
    @IntrusionCM ok

    No I have not read up in V8 internals.

    but javascript number is still a double so v8 then might identify where your only doing integer math and might optimize away parseInt calls.

    That might work.

    Bun unless there is some way to enforce it, it will require you to diligently ensure you always does what is required to keep it as integers.

    Still, most games use float or double, especially for positions unless you have s fixed grid navigation.
  • 3
    sigh.

    Most didn't get the point at all.

    But after rereading comments here I must say that it's sad - @Root gave an excellent comment which was far superior to mine.

    And instead of understanding that in most cases floats don't matter - unless YOU decide that they matter - and that the most common compiler V8 doesn't use floats for - internal - representation of Number in JS, but instead integer's unless it's unavoidable...

    You just scream to use floats because float.

    That's exactly the vibe I'm getting here.

    I can partially understand @Demolishun comment - but if V8 uses 31 bit integers unless explicitly required, I guess they have a very good reason to do so.

    We're talking about JavaScript in vanilla which is the most shitty thing regarding types.

    And instead of going the sane way and just trying to avoid it, you insist it must be float all the way.

    That's just dumb.
  • 0
    @IntrusionCM No, use floats for float math and integers for integer math. But avoiding floats because of precision issues is not going to help. Understanding that there are precision issues is the key.
Add Comment