float/double Math.Round in C# [duplicate]
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?
c# rounding
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.
|
show 8 more comments
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?
c# rounding
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 whyfloat
exists.
– SeM
8 hours ago
4
@i486 Again, that doesn't mean, that you should never usefloat
.
– 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 as31.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
|
show 8 more comments
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?
c# rounding
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
c# rounding
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 whyfloat
exists.
– SeM
8 hours ago
4
@i486 Again, that doesn't mean, that you should never usefloat
.
– 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 as31.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
|
show 8 more comments
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 whyfloat
exists.
– SeM
8 hours ago
4
@i486 Again, that doesn't mean, that you should never usefloat
.
– 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 as31.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
|
show 8 more comments
2 Answers
2
active
oldest
votes
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
I'm curious why(double)ff
is exactly31.14999961853027
and not31.150000000000000
– Gonzalo Lorieto
8 hours ago
7
@Gonzalo Lorieto:double
is binary and0.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
add a comment |
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.
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
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
I'm curious why(double)ff
is exactly31.14999961853027
and not31.150000000000000
– Gonzalo Lorieto
8 hours ago
7
@Gonzalo Lorieto:double
is binary and0.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
add a comment |
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
I'm curious why(double)ff
is exactly31.14999961853027
and not31.150000000000000
– Gonzalo Lorieto
8 hours ago
7
@Gonzalo Lorieto:double
is binary and0.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
add a comment |
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
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
answered 8 hours ago
Dmitry BychenkoDmitry Bychenko
107k1093133
107k1093133
I'm curious why(double)ff
is exactly31.14999961853027
and not31.150000000000000
– Gonzalo Lorieto
8 hours ago
7
@Gonzalo Lorieto:double
is binary and0.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
add a comment |
I'm curious why(double)ff
is exactly31.14999961853027
and not31.150000000000000
– Gonzalo Lorieto
8 hours ago
7
@Gonzalo Lorieto:double
is binary and0.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
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
edited 8 hours ago
answered 8 hours ago
BenBen
28.8k55488
28.8k55488
add a comment |
add a comment |
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 as31.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