Code Monkey home page Code Monkey logo

Comments (2)

cuviper avatar cuviper commented on September 26, 2024

I took your example from the rust bug and added the raw bits, as well as specifying the display precision: playground

use num::range;

fn main() {
    let (start, end) = (0.01, 128.99);

    for n in range(start, end) {
        println!("{:064b} = {:.30}", f64::to_bits(n), n);
    }
}
output
0011111110000100011110101110000101000111101011100001010001111011 = 0.010000000000000000208166817117
0011111111110000001010001111010111000010100011110101110000101001 = 1.010000000000000008881784197001
0100000000000000000101000111101011100001010001111010111000010100 = 2.009999999999999786837179271970
0100000000001000000101000111101011100001010001111010111000010100 = 3.009999999999999786837179271970
0100000000010000000010100011110101110000101000111101011100001010 = 4.009999999999999786837179271970
0100000000010100000010100011110101110000101000111101011100001010 = 5.009999999999999786837179271970
0100000000011000000010100011110101110000101000111101011100001010 = 6.009999999999999786837179271970
0100000000011100000010100011110101110000101000111101011100001010 = 7.009999999999999786837179271970
0100000000100000000001010001111010111000010100011110101110000101 = 8.009999999999999786837179271970
0100000000100010000001010001111010111000010100011110101110000101 = 9.009999999999999786837179271970
0100000000100100000001010001111010111000010100011110101110000101 = 10.009999999999999786837179271970
0100000000100110000001010001111010111000010100011110101110000101 = 11.009999999999999786837179271970
0100000000101000000001010001111010111000010100011110101110000101 = 12.009999999999999786837179271970
0100000000101010000001010001111010111000010100011110101110000101 = 13.009999999999999786837179271970
0100000000101100000001010001111010111000010100011110101110000101 = 14.009999999999999786837179271970
0100000000101110000001010001111010111000010100011110101110000101 = 15.009999999999999786837179271970
0100000000110000000000101000111101011100001010001111010111000010 = 16.009999999999998010480339871719
0100000000110001000000101000111101011100001010001111010111000010 = 17.009999999999998010480339871719
0100000000110010000000101000111101011100001010001111010111000010 = 18.009999999999998010480339871719
0100000000110011000000101000111101011100001010001111010111000010 = 19.009999999999998010480339871719
0100000000110100000000101000111101011100001010001111010111000010 = 20.009999999999998010480339871719
0100000000110101000000101000111101011100001010001111010111000010 = 21.009999999999998010480339871719
0100000000110110000000101000111101011100001010001111010111000010 = 22.009999999999998010480339871719
0100000000110111000000101000111101011100001010001111010111000010 = 23.009999999999998010480339871719
0100000000111000000000101000111101011100001010001111010111000010 = 24.009999999999998010480339871719
0100000000111001000000101000111101011100001010001111010111000010 = 25.009999999999998010480339871719
0100000000111010000000101000111101011100001010001111010111000010 = 26.009999999999998010480339871719
0100000000111011000000101000111101011100001010001111010111000010 = 27.009999999999998010480339871719
0100000000111100000000101000111101011100001010001111010111000010 = 28.009999999999998010480339871719
0100000000111101000000101000111101011100001010001111010111000010 = 29.009999999999998010480339871719
0100000000111110000000101000111101011100001010001111010111000010 = 30.009999999999998010480339871719
0100000000111111000000101000111101011100001010001111010111000010 = 31.009999999999998010480339871719
0100000001000000000000010100011110101110000101000111101011100001 = 32.009999999999998010480339871719
0100000001000000100000010100011110101110000101000111101011100001 = 33.009999999999998010480339871719
0100000001000001000000010100011110101110000101000111101011100001 = 34.009999999999998010480339871719
0100000001000001100000010100011110101110000101000111101011100001 = 35.009999999999998010480339871719
0100000001000010000000010100011110101110000101000111101011100001 = 36.009999999999998010480339871719
0100000001000010100000010100011110101110000101000111101011100001 = 37.009999999999998010480339871719
0100000001000011000000010100011110101110000101000111101011100001 = 38.009999999999998010480339871719
0100000001000011100000010100011110101110000101000111101011100001 = 39.009999999999998010480339871719
0100000001000100000000010100011110101110000101000111101011100001 = 40.009999999999998010480339871719
0100000001000100100000010100011110101110000101000111101011100001 = 41.009999999999998010480339871719
0100000001000101000000010100011110101110000101000111101011100001 = 42.009999999999998010480339871719
0100000001000101100000010100011110101110000101000111101011100001 = 43.009999999999998010480339871719
0100000001000110000000010100011110101110000101000111101011100001 = 44.009999999999998010480339871719
0100000001000110100000010100011110101110000101000111101011100001 = 45.009999999999998010480339871719
0100000001000111000000010100011110101110000101000111101011100001 = 46.009999999999998010480339871719
0100000001000111100000010100011110101110000101000111101011100001 = 47.009999999999998010480339871719
0100000001001000000000010100011110101110000101000111101011100001 = 48.009999999999998010480339871719
0100000001001000100000010100011110101110000101000111101011100001 = 49.009999999999998010480339871719
0100000001001001000000010100011110101110000101000111101011100001 = 50.009999999999998010480339871719
0100000001001001100000010100011110101110000101000111101011100001 = 51.009999999999998010480339871719
0100000001001010000000010100011110101110000101000111101011100001 = 52.009999999999998010480339871719
0100000001001010100000010100011110101110000101000111101011100001 = 53.009999999999998010480339871719
0100000001001011000000010100011110101110000101000111101011100001 = 54.009999999999998010480339871719
0100000001001011100000010100011110101110000101000111101011100001 = 55.009999999999998010480339871719
0100000001001100000000010100011110101110000101000111101011100001 = 56.009999999999998010480339871719
0100000001001100100000010100011110101110000101000111101011100001 = 57.009999999999998010480339871719
0100000001001101000000010100011110101110000101000111101011100001 = 58.009999999999998010480339871719
0100000001001101100000010100011110101110000101000111101011100001 = 59.009999999999998010480339871719
0100000001001110000000010100011110101110000101000111101011100001 = 60.009999999999998010480339871719
0100000001001110100000010100011110101110000101000111101011100001 = 61.009999999999998010480339871719
0100000001001111000000010100011110101110000101000111101011100001 = 62.009999999999998010480339871719
0100000001001111100000010100011110101110000101000111101011100001 = 63.009999999999998010480339871719
0100000001010000000000001010001111010111000010100011110101110000 = 64.009999999999990905052982270718
0100000001010000010000001010001111010111000010100011110101110000 = 65.009999999999990905052982270718
0100000001010000100000001010001111010111000010100011110101110000 = 66.009999999999990905052982270718
0100000001010000110000001010001111010111000010100011110101110000 = 67.009999999999990905052982270718
0100000001010001000000001010001111010111000010100011110101110000 = 68.009999999999990905052982270718
0100000001010001010000001010001111010111000010100011110101110000 = 69.009999999999990905052982270718
0100000001010001100000001010001111010111000010100011110101110000 = 70.009999999999990905052982270718
0100000001010001110000001010001111010111000010100011110101110000 = 71.009999999999990905052982270718
0100000001010010000000001010001111010111000010100011110101110000 = 72.009999999999990905052982270718
0100000001010010010000001010001111010111000010100011110101110000 = 73.009999999999990905052982270718
0100000001010010100000001010001111010111000010100011110101110000 = 74.009999999999990905052982270718
0100000001010010110000001010001111010111000010100011110101110000 = 75.009999999999990905052982270718
0100000001010011000000001010001111010111000010100011110101110000 = 76.009999999999990905052982270718
0100000001010011010000001010001111010111000010100011110101110000 = 77.009999999999990905052982270718
0100000001010011100000001010001111010111000010100011110101110000 = 78.009999999999990905052982270718
0100000001010011110000001010001111010111000010100011110101110000 = 79.009999999999990905052982270718
0100000001010100000000001010001111010111000010100011110101110000 = 80.009999999999990905052982270718
0100000001010100010000001010001111010111000010100011110101110000 = 81.009999999999990905052982270718
0100000001010100100000001010001111010111000010100011110101110000 = 82.009999999999990905052982270718
0100000001010100110000001010001111010111000010100011110101110000 = 83.009999999999990905052982270718
0100000001010101000000001010001111010111000010100011110101110000 = 84.009999999999990905052982270718
0100000001010101010000001010001111010111000010100011110101110000 = 85.009999999999990905052982270718
0100000001010101100000001010001111010111000010100011110101110000 = 86.009999999999990905052982270718
0100000001010101110000001010001111010111000010100011110101110000 = 87.009999999999990905052982270718
0100000001010110000000001010001111010111000010100011110101110000 = 88.009999999999990905052982270718
0100000001010110010000001010001111010111000010100011110101110000 = 89.009999999999990905052982270718
0100000001010110100000001010001111010111000010100011110101110000 = 90.009999999999990905052982270718
0100000001010110110000001010001111010111000010100011110101110000 = 91.009999999999990905052982270718
0100000001010111000000001010001111010111000010100011110101110000 = 92.009999999999990905052982270718
0100000001010111010000001010001111010111000010100011110101110000 = 93.009999999999990905052982270718
0100000001010111100000001010001111010111000010100011110101110000 = 94.009999999999990905052982270718
0100000001010111110000001010001111010111000010100011110101110000 = 95.009999999999990905052982270718
0100000001011000000000001010001111010111000010100011110101110000 = 96.009999999999990905052982270718
0100000001011000010000001010001111010111000010100011110101110000 = 97.009999999999990905052982270718
0100000001011000100000001010001111010111000010100011110101110000 = 98.009999999999990905052982270718
0100000001011000110000001010001111010111000010100011110101110000 = 99.009999999999990905052982270718
0100000001011001000000001010001111010111000010100011110101110000 = 100.009999999999990905052982270718
0100000001011001010000001010001111010111000010100011110101110000 = 101.009999999999990905052982270718
0100000001011001100000001010001111010111000010100011110101110000 = 102.009999999999990905052982270718
0100000001011001110000001010001111010111000010100011110101110000 = 103.009999999999990905052982270718
0100000001011010000000001010001111010111000010100011110101110000 = 104.009999999999990905052982270718
0100000001011010010000001010001111010111000010100011110101110000 = 105.009999999999990905052982270718
0100000001011010100000001010001111010111000010100011110101110000 = 106.009999999999990905052982270718
0100000001011010110000001010001111010111000010100011110101110000 = 107.009999999999990905052982270718
0100000001011011000000001010001111010111000010100011110101110000 = 108.009999999999990905052982270718
0100000001011011010000001010001111010111000010100011110101110000 = 109.009999999999990905052982270718
0100000001011011100000001010001111010111000010100011110101110000 = 110.009999999999990905052982270718
0100000001011011110000001010001111010111000010100011110101110000 = 111.009999999999990905052982270718
0100000001011100000000001010001111010111000010100011110101110000 = 112.009999999999990905052982270718
0100000001011100010000001010001111010111000010100011110101110000 = 113.009999999999990905052982270718
0100000001011100100000001010001111010111000010100011110101110000 = 114.009999999999990905052982270718
0100000001011100110000001010001111010111000010100011110101110000 = 115.009999999999990905052982270718
0100000001011101000000001010001111010111000010100011110101110000 = 116.009999999999990905052982270718
0100000001011101010000001010001111010111000010100011110101110000 = 117.009999999999990905052982270718
0100000001011101100000001010001111010111000010100011110101110000 = 118.009999999999990905052982270718
0100000001011101110000001010001111010111000010100011110101110000 = 119.009999999999990905052982270718
0100000001011110000000001010001111010111000010100011110101110000 = 120.009999999999990905052982270718
0100000001011110010000001010001111010111000010100011110101110000 = 121.009999999999990905052982270718
0100000001011110100000001010001111010111000010100011110101110000 = 122.009999999999990905052982270718
0100000001011110110000001010001111010111000010100011110101110000 = 123.009999999999990905052982270718
0100000001011111000000001010001111010111000010100011110101110000 = 124.009999999999990905052982270718
0100000001011111010000001010001111010111000010100011110101110000 = 125.009999999999990905052982270718
0100000001011111100000001010001111010111000010100011110101110000 = 126.009999999999990905052982270718
0100000001011111110000001010001111010111000010100011110101110000 = 127.009999999999990905052982270718
0100000001100000000000000101000111101011100001010001111010111000 = 128.009999999999990905052982270718

You can see that the values are in fact steadily increasing -- but 0.01 is not exact in binary. Whenever the most-significant bit increases, like 7 to 8, 15 to 16, etc., we lose one of the least-significant bits in the mantissa. If that lost bit was a 1, then the approximation of the fractional part changes.

Rust's default "{}" formatting for floats tries to find the shortest decimal approximation that would parse back to the same value. Sometimes X.01 will satisfy that, but sometimes not, particularly when the LSB is 0 but X.01 would be closer with a 1 LSB.

You can reproduce this difference without num too:

fn main() {
    for &n in &[15.01, 15.01 + 1.0, 16.01] {
        println!("{:064b} = {:.30} ~= {}", f64::to_bits(n), n, n);
    }
}
0100000000101110000001010001111010111000010100011110101110000101 = 15.009999999999999786837179271970 ~= 15.01
0100000000110000000000101000111101011100001010001111010111000010 = 16.009999999999998010480339871719 ~= 16.009999999999998
0100000000110000000000101000111101011100001010001111010111000011 = 16.010000000000001563194018672220 ~= 16.01

from num.

tuxiqae avatar tuxiqae commented on September 26, 2024

Thanks for the detailed explanation and for making this wonderful crate.

from num.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.