I was working on a project lately where I needed to convert an array of bits (1s and 0s) to floating numbers.

It is quite straightforward how to convert an array of bits to the simple integer (i.e. [101] = 5). But what about the numbers like `3.1415` (𝝿) or `9.109 × 10⁻³¹` (the mass of the electron in kg)?

I've explored this question a bit and came up with a diagram that explains how the float numbers are actually stored.

There is also an interactive version of this diagram available here https://trekhleb.dev/blog/2021/....

Feel free to experiment with it and play around with setting the bits on and off and see how it influences the final result.

  • 3
    Man it's so anti intuitive.
    Thank you so much for this!
  • 1
    @c3r38r170 haha, sorry to hear that it was anti-intuitive. I hope you didn't waste too much time on it, since the article is pretty short :)
  • 1
    @trekhleb I meant the system, it's really complex and you can't see how it works / behaves at first sight.
    The article is awesome!
  • 1
    Oh man I saw you added it to the article I feel so bad for not expressing properly!
    It's great! I even shared it to a popular local IT group.
  • 2
    @c3r38r170 ah, I guess I've misunderstood :D I'm glad you liked the article! And by the way, the "anti-intuitive" part I really liked so much that I couldn't resist adding this phrase to the article. It is a bit more fun now :)
  • 5
    Why the "devrant" tag? That has nothing to do with devRant. The "devrant" tag does not mean "developer rant" because there are only devs here - no finance, HR, and sales folks.

    Otherwise, good article - could you add more examples? In particular, how 0.1 converts to float, and what happens when you add that up? That would explain why you don't do 0.1 step loops, but instead use integer loops and divide by 10.0 inside the loop. Or use 1/8 or 1/16 as steps, showing that these have an exact representation in float.

    Also, the classic example of how 0.1 and 0.2 don't add up to 0.3 on binary level so that all the JavaScript noobs don't misattribute this as a JS defect.

    And finally, that you never compare for equality on floats, only on intervals (half-open ones included).
  • 4
    @trekhleb Great article! I agree with @Fast-Nop about more examples, and I think it's pretty important to cover NaN and infinities.

    Also, for an interesting aside, perhaps you could cover denormals, which are relatively unknown and under-appreciated (double precision denormals are kinda useless, but single precision ones are quite useful for numerical methods, and convenient when using double precision introduces too much memory pressure).
  • 1
    Thanks for the good advice, folks! I'll try to find time to extend the article with more examples that you've mentioned
  • 0
    Literally. ANY high level language does all of that for you. No need to do it by hand
  • 2
    @NoToJavaScript you should still know how it works, otherwise you'll try looping with an unrepresentable float increment or trying.to compare stuff, or screwing calculations up. High level languages won't help you there.
  • 2
    @NoToJavaScript As soon as you work with floats (same for doubles of course) in ANY language, you have to understand how they work.

    Otherwise, you will not only fuck up, but also fail to understand what the problem is and thus be unable to fix it.

    Your claim that a higher level language would solve that puts you firmly in exactly that fuck-up camp.
  • 0
    Brings me back to university
  • 0
    I don‘t agree that you need to know how float works to avoid the mistakes.
    It certainly helps but it‘s not necessary.
    You just need to know the weird properties of float.
    You won‘t be converting float representations manually to check if your code using float numbers is ok. :)
    Also, knowing how it works doesn’t automatically grant you all the knowledge about its pitfalls.
Add Comment