float/double Math.Round in C# [duplicate]

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP












17
















This question already has an answer here:



  • Is floating point math broken?

    28 answers



  • Rounding of float values

    2 answers



  • Difference between decimal, float and double in .NET?

    16 answers



float ff = (float)31.15;

double dd = 31.15;

var frst = Math.Round(ff, 1, MidpointRounding.AwayFromZero);

var drst = Math.Round(dd, 1, MidpointRounding.AwayFromZero);


frst: 31.1



drst: 31.2



Can someone explain why?










share|improve this question















marked as duplicate by mjwills, SeM, Wai Ha Lee, phuclv, YSC Jan 17 at 17:45


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.













  • 3





    Because (float)31.15 is not equal to (double)31.15. Floating-point-arithmetic allmost allways yields to rounding-erros. In paticular rounding a double works different from rounding a float.

    – HimBromBeere
    Jan 17 at 12:26







  • 1





    Rounding errors are unavoidable with floating point values. They are as unavoidable as death and taxes : youtube.com/watch?v=PZRI1IfStY0

    – Christopher
    Jan 17 at 12:31






  • 4





    @i486 Well, not always, there is a reason why float exists.

    – SeM
    Jan 17 at 12:33






  • 4





    @i486 Again, that doesn't mean, that you should never use float.

    – SeM
    Jan 17 at 13:29






  • 4





    Where are the C# gold badges? IMHO this should have been closed as dup in the first 17s, not 5 hours after!

    – YSC
    Jan 17 at 17:47
















17
















This question already has an answer here:



  • Is floating point math broken?

    28 answers



  • Rounding of float values

    2 answers



  • Difference between decimal, float and double in .NET?

    16 answers



float ff = (float)31.15;

double dd = 31.15;

var frst = Math.Round(ff, 1, MidpointRounding.AwayFromZero);

var drst = Math.Round(dd, 1, MidpointRounding.AwayFromZero);


frst: 31.1



drst: 31.2



Can someone explain why?










share|improve this question















marked as duplicate by mjwills, SeM, Wai Ha Lee, phuclv, YSC Jan 17 at 17:45


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.













  • 3





    Because (float)31.15 is not equal to (double)31.15. Floating-point-arithmetic allmost allways yields to rounding-erros. In paticular rounding a double works different from rounding a float.

    – HimBromBeere
    Jan 17 at 12:26







  • 1





    Rounding errors are unavoidable with floating point values. They are as unavoidable as death and taxes : youtube.com/watch?v=PZRI1IfStY0

    – Christopher
    Jan 17 at 12:31






  • 4





    @i486 Well, not always, there is a reason why float exists.

    – SeM
    Jan 17 at 12:33






  • 4





    @i486 Again, that doesn't mean, that you should never use float.

    – SeM
    Jan 17 at 13:29






  • 4





    Where are the C# gold badges? IMHO this should have been closed as dup in the first 17s, not 5 hours after!

    – YSC
    Jan 17 at 17:47














17












17








17


1







This question already has an answer here:



  • Is floating point math broken?

    28 answers



  • Rounding of float values

    2 answers



  • Difference between decimal, float and double in .NET?

    16 answers



float ff = (float)31.15;

double dd = 31.15;

var frst = Math.Round(ff, 1, MidpointRounding.AwayFromZero);

var drst = Math.Round(dd, 1, MidpointRounding.AwayFromZero);


frst: 31.1



drst: 31.2



Can someone explain why?










share|improve this question

















This question already has an answer here:



  • Is floating point math broken?

    28 answers



  • Rounding of float values

    2 answers



  • Difference between decimal, float and double in .NET?

    16 answers



float ff = (float)31.15;

double dd = 31.15;

var frst = Math.Round(ff, 1, MidpointRounding.AwayFromZero);

var drst = Math.Round(dd, 1, MidpointRounding.AwayFromZero);


frst: 31.1



drst: 31.2



Can someone explain why?





This question already has an answer here:



  • Is floating point math broken?

    28 answers



  • Rounding of float values

    2 answers



  • Difference between decimal, float and double in .NET?

    16 answers







c# rounding






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 17 at 12:50









Dmitry Bychenko

107k1093133




107k1093133










asked Jan 17 at 12:22









YaoqingYaoqing

1182




1182




marked as duplicate by mjwills, SeM, Wai Ha Lee, phuclv, YSC Jan 17 at 17:45


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.









marked as duplicate by mjwills, SeM, Wai Ha Lee, phuclv, YSC Jan 17 at 17:45


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.









  • 3





    Because (float)31.15 is not equal to (double)31.15. Floating-point-arithmetic allmost allways yields to rounding-erros. In paticular rounding a double works different from rounding a float.

    – HimBromBeere
    Jan 17 at 12:26







  • 1





    Rounding errors are unavoidable with floating point values. They are as unavoidable as death and taxes : youtube.com/watch?v=PZRI1IfStY0

    – Christopher
    Jan 17 at 12:31






  • 4





    @i486 Well, not always, there is a reason why float exists.

    – SeM
    Jan 17 at 12:33






  • 4





    @i486 Again, that doesn't mean, that you should never use float.

    – SeM
    Jan 17 at 13:29






  • 4





    Where are the C# gold badges? IMHO this should have been closed as dup in the first 17s, not 5 hours after!

    – YSC
    Jan 17 at 17:47













  • 3





    Because (float)31.15 is not equal to (double)31.15. Floating-point-arithmetic allmost allways yields to rounding-erros. In paticular rounding a double works different from rounding a float.

    – HimBromBeere
    Jan 17 at 12:26







  • 1





    Rounding errors are unavoidable with floating point values. They are as unavoidable as death and taxes : youtube.com/watch?v=PZRI1IfStY0

    – Christopher
    Jan 17 at 12:31






  • 4





    @i486 Well, not always, there is a reason why float exists.

    – SeM
    Jan 17 at 12:33






  • 4





    @i486 Again, that doesn't mean, that you should never use float.

    – SeM
    Jan 17 at 13:29






  • 4





    Where are the C# gold badges? IMHO this should have been closed as dup in the first 17s, not 5 hours after!

    – YSC
    Jan 17 at 17:47








3




3





Because (float)31.15 is not equal to (double)31.15. Floating-point-arithmetic allmost allways yields to rounding-erros. In paticular rounding a double works different from rounding a float.

– HimBromBeere
Jan 17 at 12:26






Because (float)31.15 is not equal to (double)31.15. Floating-point-arithmetic allmost allways yields to rounding-erros. In paticular rounding a double works different from rounding a float.

– HimBromBeere
Jan 17 at 12:26





1




1





Rounding errors are unavoidable with floating point values. They are as unavoidable as death and taxes : youtube.com/watch?v=PZRI1IfStY0

– Christopher
Jan 17 at 12:31





Rounding errors are unavoidable with floating point values. They are as unavoidable as death and taxes : youtube.com/watch?v=PZRI1IfStY0

– Christopher
Jan 17 at 12:31




4




4





@i486 Well, not always, there is a reason why float exists.

– SeM
Jan 17 at 12:33





@i486 Well, not always, there is a reason why float exists.

– SeM
Jan 17 at 12:33




4




4





@i486 Again, that doesn't mean, that you should never use float.

– SeM
Jan 17 at 13:29





@i486 Again, that doesn't mean, that you should never use float.

– SeM
Jan 17 at 13:29




4




4





Where are the C# gold badges? IMHO this should have been closed as dup in the first 17s, not 5 hours after!

– YSC
Jan 17 at 17:47






Where are the C# gold badges? IMHO this should have been closed as dup in the first 17s, not 5 hours after!

– YSC
Jan 17 at 17:47













2 Answers
2






active

oldest

votes


















26














Well, Math.Round wants double, not float, that's why



Math.Round(ff, 1, MidpointRounding.AwayFromZero);


equals to



Math.Round((double)ff, 1, MidpointRounding.AwayFromZero);


and if we inspect (double)ff value



Console.Write(((double)ff).ToString("R"));


we'll see round up errors in action



31.149999618530273


Finally, Math.Round(31.149999618530273, 1, MidpointRounding.AwayFromZero) == 31.1 as expected






share|improve this answer























  • I'm curious why (double)ff is exactly 31.14999961853027 and not 31.150000000000000

    – Gonzalo Lorieto
    Jan 17 at 12:34






  • 7





    @Gonzalo Lorieto: double is binary and 0.15 == 15 / 100 = 3 / 20 is a periodic fraction in binary representation.

    – Dmitry Bychenko
    Jan 17 at 12:35






  • 1





    @GonzaloLorieto stackoverflow.com/questions/618535/…

    – Camilo Terevinto
    Jan 17 at 12:35






  • 1





    @GonzaloLorieto You can read it here -> Floating-point arithmetic

    – SeM
    Jan 17 at 12:35


















12














In floating point, all numbers are represented internally as fractions where the denominator is a power of 2.



(This is a similar way to how decimals are actually fractions with power-of-10 denominators. So 31.15 is just a way of writing the fraction 3115/100)



In floating point, 31.15 must be represented internally as a binary number. The closest binary fraction is: 1111.1001001100110011001100110011001100110011001100110011001100...repeating



The 1100 recurs (repeats forever), and so the number will be truncated depending on whether it is stored in a double or a float. In a float it is truncated to 24 digits, and in a double to 53.



Exact: 1111.100100110011001100110011001100110011001100110011001100110011001100...forever
Float: 1111.10010011001100110011
Double: 1111.1001001100110011001100110011001100110011001100110


Therefore you can see that the double that this number converts to, is actually slightly larger than the float it converts to. So it is clear that it won't necessarily round to the same number, since it is not the same number to begin with.






share|improve this answer































    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    26














    Well, Math.Round wants double, not float, that's why



    Math.Round(ff, 1, MidpointRounding.AwayFromZero);


    equals to



    Math.Round((double)ff, 1, MidpointRounding.AwayFromZero);


    and if we inspect (double)ff value



    Console.Write(((double)ff).ToString("R"));


    we'll see round up errors in action



    31.149999618530273


    Finally, Math.Round(31.149999618530273, 1, MidpointRounding.AwayFromZero) == 31.1 as expected






    share|improve this answer























    • I'm curious why (double)ff is exactly 31.14999961853027 and not 31.150000000000000

      – Gonzalo Lorieto
      Jan 17 at 12:34






    • 7





      @Gonzalo Lorieto: double is binary and 0.15 == 15 / 100 = 3 / 20 is a periodic fraction in binary representation.

      – Dmitry Bychenko
      Jan 17 at 12:35






    • 1





      @GonzaloLorieto stackoverflow.com/questions/618535/…

      – Camilo Terevinto
      Jan 17 at 12:35






    • 1





      @GonzaloLorieto You can read it here -> Floating-point arithmetic

      – SeM
      Jan 17 at 12:35















    26














    Well, Math.Round wants double, not float, that's why



    Math.Round(ff, 1, MidpointRounding.AwayFromZero);


    equals to



    Math.Round((double)ff, 1, MidpointRounding.AwayFromZero);


    and if we inspect (double)ff value



    Console.Write(((double)ff).ToString("R"));


    we'll see round up errors in action



    31.149999618530273


    Finally, Math.Round(31.149999618530273, 1, MidpointRounding.AwayFromZero) == 31.1 as expected






    share|improve this answer























    • I'm curious why (double)ff is exactly 31.14999961853027 and not 31.150000000000000

      – Gonzalo Lorieto
      Jan 17 at 12:34






    • 7





      @Gonzalo Lorieto: double is binary and 0.15 == 15 / 100 = 3 / 20 is a periodic fraction in binary representation.

      – Dmitry Bychenko
      Jan 17 at 12:35






    • 1





      @GonzaloLorieto stackoverflow.com/questions/618535/…

      – Camilo Terevinto
      Jan 17 at 12:35






    • 1





      @GonzaloLorieto You can read it here -> Floating-point arithmetic

      – SeM
      Jan 17 at 12:35













    26












    26








    26







    Well, Math.Round wants double, not float, that's why



    Math.Round(ff, 1, MidpointRounding.AwayFromZero);


    equals to



    Math.Round((double)ff, 1, MidpointRounding.AwayFromZero);


    and if we inspect (double)ff value



    Console.Write(((double)ff).ToString("R"));


    we'll see round up errors in action



    31.149999618530273


    Finally, Math.Round(31.149999618530273, 1, MidpointRounding.AwayFromZero) == 31.1 as expected






    share|improve this answer













    Well, Math.Round wants double, not float, that's why



    Math.Round(ff, 1, MidpointRounding.AwayFromZero);


    equals to



    Math.Round((double)ff, 1, MidpointRounding.AwayFromZero);


    and if we inspect (double)ff value



    Console.Write(((double)ff).ToString("R"));


    we'll see round up errors in action



    31.149999618530273


    Finally, Math.Round(31.149999618530273, 1, MidpointRounding.AwayFromZero) == 31.1 as expected







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Jan 17 at 12:29









    Dmitry BychenkoDmitry Bychenko

    107k1093133




    107k1093133












    • I'm curious why (double)ff is exactly 31.14999961853027 and not 31.150000000000000

      – Gonzalo Lorieto
      Jan 17 at 12:34






    • 7





      @Gonzalo Lorieto: double is binary and 0.15 == 15 / 100 = 3 / 20 is a periodic fraction in binary representation.

      – Dmitry Bychenko
      Jan 17 at 12:35






    • 1





      @GonzaloLorieto stackoverflow.com/questions/618535/…

      – Camilo Terevinto
      Jan 17 at 12:35






    • 1





      @GonzaloLorieto You can read it here -> Floating-point arithmetic

      – SeM
      Jan 17 at 12:35

















    • I'm curious why (double)ff is exactly 31.14999961853027 and not 31.150000000000000

      – Gonzalo Lorieto
      Jan 17 at 12:34






    • 7





      @Gonzalo Lorieto: double is binary and 0.15 == 15 / 100 = 3 / 20 is a periodic fraction in binary representation.

      – Dmitry Bychenko
      Jan 17 at 12:35






    • 1





      @GonzaloLorieto stackoverflow.com/questions/618535/…

      – Camilo Terevinto
      Jan 17 at 12:35






    • 1





      @GonzaloLorieto You can read it here -> Floating-point arithmetic

      – SeM
      Jan 17 at 12:35
















    I'm curious why (double)ff is exactly 31.14999961853027 and not 31.150000000000000

    – Gonzalo Lorieto
    Jan 17 at 12:34





    I'm curious why (double)ff is exactly 31.14999961853027 and not 31.150000000000000

    – Gonzalo Lorieto
    Jan 17 at 12:34




    7




    7





    @Gonzalo Lorieto: double is binary and 0.15 == 15 / 100 = 3 / 20 is a periodic fraction in binary representation.

    – Dmitry Bychenko
    Jan 17 at 12:35





    @Gonzalo Lorieto: double is binary and 0.15 == 15 / 100 = 3 / 20 is a periodic fraction in binary representation.

    – Dmitry Bychenko
    Jan 17 at 12:35




    1




    1





    @GonzaloLorieto stackoverflow.com/questions/618535/…

    – Camilo Terevinto
    Jan 17 at 12:35





    @GonzaloLorieto stackoverflow.com/questions/618535/…

    – Camilo Terevinto
    Jan 17 at 12:35




    1




    1





    @GonzaloLorieto You can read it here -> Floating-point arithmetic

    – SeM
    Jan 17 at 12:35





    @GonzaloLorieto You can read it here -> Floating-point arithmetic

    – SeM
    Jan 17 at 12:35













    12














    In floating point, all numbers are represented internally as fractions where the denominator is a power of 2.



    (This is a similar way to how decimals are actually fractions with power-of-10 denominators. So 31.15 is just a way of writing the fraction 3115/100)



    In floating point, 31.15 must be represented internally as a binary number. The closest binary fraction is: 1111.1001001100110011001100110011001100110011001100110011001100...repeating



    The 1100 recurs (repeats forever), and so the number will be truncated depending on whether it is stored in a double or a float. In a float it is truncated to 24 digits, and in a double to 53.



    Exact: 1111.100100110011001100110011001100110011001100110011001100110011001100...forever
    Float: 1111.10010011001100110011
    Double: 1111.1001001100110011001100110011001100110011001100110


    Therefore you can see that the double that this number converts to, is actually slightly larger than the float it converts to. So it is clear that it won't necessarily round to the same number, since it is not the same number to begin with.






    share|improve this answer





























      12














      In floating point, all numbers are represented internally as fractions where the denominator is a power of 2.



      (This is a similar way to how decimals are actually fractions with power-of-10 denominators. So 31.15 is just a way of writing the fraction 3115/100)



      In floating point, 31.15 must be represented internally as a binary number. The closest binary fraction is: 1111.1001001100110011001100110011001100110011001100110011001100...repeating



      The 1100 recurs (repeats forever), and so the number will be truncated depending on whether it is stored in a double or a float. In a float it is truncated to 24 digits, and in a double to 53.



      Exact: 1111.100100110011001100110011001100110011001100110011001100110011001100...forever
      Float: 1111.10010011001100110011
      Double: 1111.1001001100110011001100110011001100110011001100110


      Therefore you can see that the double that this number converts to, is actually slightly larger than the float it converts to. So it is clear that it won't necessarily round to the same number, since it is not the same number to begin with.






      share|improve this answer



























        12












        12








        12







        In floating point, all numbers are represented internally as fractions where the denominator is a power of 2.



        (This is a similar way to how decimals are actually fractions with power-of-10 denominators. So 31.15 is just a way of writing the fraction 3115/100)



        In floating point, 31.15 must be represented internally as a binary number. The closest binary fraction is: 1111.1001001100110011001100110011001100110011001100110011001100...repeating



        The 1100 recurs (repeats forever), and so the number will be truncated depending on whether it is stored in a double or a float. In a float it is truncated to 24 digits, and in a double to 53.



        Exact: 1111.100100110011001100110011001100110011001100110011001100110011001100...forever
        Float: 1111.10010011001100110011
        Double: 1111.1001001100110011001100110011001100110011001100110


        Therefore you can see that the double that this number converts to, is actually slightly larger than the float it converts to. So it is clear that it won't necessarily round to the same number, since it is not the same number to begin with.






        share|improve this answer















        In floating point, all numbers are represented internally as fractions where the denominator is a power of 2.



        (This is a similar way to how decimals are actually fractions with power-of-10 denominators. So 31.15 is just a way of writing the fraction 3115/100)



        In floating point, 31.15 must be represented internally as a binary number. The closest binary fraction is: 1111.1001001100110011001100110011001100110011001100110011001100...repeating



        The 1100 recurs (repeats forever), and so the number will be truncated depending on whether it is stored in a double or a float. In a float it is truncated to 24 digits, and in a double to 53.



        Exact: 1111.100100110011001100110011001100110011001100110011001100110011001100...forever
        Float: 1111.10010011001100110011
        Double: 1111.1001001100110011001100110011001100110011001100110


        Therefore you can see that the double that this number converts to, is actually slightly larger than the float it converts to. So it is clear that it won't necessarily round to the same number, since it is not the same number to begin with.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jan 17 at 13:02

























        answered Jan 17 at 12:41









        BenBen

        28.8k55588




        28.8k55588












            Popular posts from this blog

            How to check contact read email or not when send email to Individual?

            Displaying single band from multi-band raster using QGIS

            How many registers does an x86_64 CPU actually have?