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












15
















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 3 hours ago


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
    8 hours ago








  • 1





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

    – Christopher
    8 hours ago






  • 4





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

    – SeM
    8 hours ago






  • 4





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

    – SeM
    7 hours ago






  • 1





    @HimBromBeere (float)31.15 is a double value converted to float, which results in double rounding error and may not be the same as 31.15f (which is the closest value to 31.15 in float precision) Why do you need to specify an 'f' in a float literal?, Why comparing double and float leads to unexpected result?, strange output in comparison of float with float literal

    – phuclv
    6 hours ago


















15
















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 3 hours ago


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
    8 hours ago








  • 1





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

    – Christopher
    8 hours ago






  • 4





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

    – SeM
    8 hours ago






  • 4





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

    – SeM
    7 hours ago






  • 1





    @HimBromBeere (float)31.15 is a double value converted to float, which results in double rounding error and may not be the same as 31.15f (which is the closest value to 31.15 in float precision) Why do you need to specify an 'f' in a float literal?, Why comparing double and float leads to unexpected result?, strange output in comparison of float with float literal

    – phuclv
    6 hours ago
















15












15








15


2







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 8 hours ago









Dmitry Bychenko

107k1093133




107k1093133










asked 9 hours ago









YaoqingYaoqing

1082




1082




marked as duplicate by mjwills, SeM, Wai Ha Lee, phuclv, YSC 3 hours ago


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 3 hours ago


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
    8 hours ago








  • 1





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

    – Christopher
    8 hours ago






  • 4





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

    – SeM
    8 hours ago






  • 4





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

    – SeM
    7 hours ago






  • 1





    @HimBromBeere (float)31.15 is a double value converted to float, which results in double rounding error and may not be the same as 31.15f (which is the closest value to 31.15 in float precision) Why do you need to specify an 'f' in a float literal?, Why comparing double and float leads to unexpected result?, strange output in comparison of float with float literal

    – phuclv
    6 hours ago
















  • 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
    8 hours ago








  • 1





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

    – Christopher
    8 hours ago






  • 4





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

    – SeM
    8 hours ago






  • 4





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

    – SeM
    7 hours ago






  • 1





    @HimBromBeere (float)31.15 is a double value converted to float, which results in double rounding error and may not be the same as 31.15f (which is the closest value to 31.15 in float precision) Why do you need to specify an 'f' in a float literal?, Why comparing double and float leads to unexpected result?, strange output in comparison of float with float literal

    – phuclv
    6 hours ago










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
8 hours ago







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
8 hours ago






1




1





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

– Christopher
8 hours ago





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

– Christopher
8 hours ago




4




4





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

– SeM
8 hours ago





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

– SeM
8 hours ago




4




4





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

– SeM
7 hours ago





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

– SeM
7 hours ago




1




1





@HimBromBeere (float)31.15 is a double value converted to float, which results in double rounding error and may not be the same as 31.15f (which is the closest value to 31.15 in float precision) Why do you need to specify an 'f' in a float literal?, Why comparing double and float leads to unexpected result?, strange output in comparison of float with float literal

– phuclv
6 hours ago







@HimBromBeere (float)31.15 is a double value converted to float, which results in double rounding error and may not be the same as 31.15f (which is the closest value to 31.15 in float precision) Why do you need to specify an 'f' in a float literal?, Why comparing double and float leads to unexpected result?, strange output in comparison of float with float literal

– phuclv
6 hours ago














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
    8 hours ago






  • 7





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

    – Dmitry Bychenko
    8 hours ago






  • 1





    @GonzaloLorieto stackoverflow.com/questions/618535/…

    – Camilo Terevinto
    8 hours ago






  • 1





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

    – SeM
    8 hours ago



















11














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
      8 hours ago






    • 7





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

      – Dmitry Bychenko
      8 hours ago






    • 1





      @GonzaloLorieto stackoverflow.com/questions/618535/…

      – Camilo Terevinto
      8 hours ago






    • 1





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

      – SeM
      8 hours ago
















    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
      8 hours ago






    • 7





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

      – Dmitry Bychenko
      8 hours ago






    • 1





      @GonzaloLorieto stackoverflow.com/questions/618535/…

      – Camilo Terevinto
      8 hours ago






    • 1





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

      – SeM
      8 hours ago














    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 8 hours ago









    Dmitry BychenkoDmitry Bychenko

    107k1093133




    107k1093133













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

      – Gonzalo Lorieto
      8 hours ago






    • 7





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

      – Dmitry Bychenko
      8 hours ago






    • 1





      @GonzaloLorieto stackoverflow.com/questions/618535/…

      – Camilo Terevinto
      8 hours ago






    • 1





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

      – SeM
      8 hours ago



















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

      – Gonzalo Lorieto
      8 hours ago






    • 7





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

      – Dmitry Bychenko
      8 hours ago






    • 1





      @GonzaloLorieto stackoverflow.com/questions/618535/…

      – Camilo Terevinto
      8 hours ago






    • 1





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

      – SeM
      8 hours ago

















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

    – Gonzalo Lorieto
    8 hours ago





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

    – Gonzalo Lorieto
    8 hours ago




    7




    7





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

    – Dmitry Bychenko
    8 hours ago





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

    – Dmitry Bychenko
    8 hours ago




    1




    1





    @GonzaloLorieto stackoverflow.com/questions/618535/…

    – Camilo Terevinto
    8 hours ago





    @GonzaloLorieto stackoverflow.com/questions/618535/…

    – Camilo Terevinto
    8 hours ago




    1




    1





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

    – SeM
    8 hours ago





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

    – SeM
    8 hours ago













    11














    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






























      11














      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




























        11












        11








        11







        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 8 hours ago

























        answered 8 hours ago









        BenBen

        28.8k55488




        28.8k55488















            Popular posts from this blog

            GameSpot

            日野市

            Tu-95轟炸機