float/double Math.Round in C# [duplicate]
Clash Royale CLAN TAG#URR8PPP
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 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.
|
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 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 whyfloat
exists.
– SeM
Jan 17 at 12:33
4
@i486 Again, that doesn't mean, that you should never usefloat
.
– 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
|
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 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 whyfloat
exists.
– SeM
Jan 17 at 12:33
4
@i486 Again, that doesn't mean, that you should never usefloat
.
– 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
|
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
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 whyfloat
exists.
– SeM
Jan 17 at 12:33
4
@i486 Again, that doesn't mean, that you should never usefloat
.
– 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
|
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
Jan 17 at 12:34
7
@Gonzalo Lorieto:double
is binary and0.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
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
Jan 17 at 12:34
7
@Gonzalo Lorieto:double
is binary and0.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
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
Jan 17 at 12:34
7
@Gonzalo Lorieto:double
is binary and0.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
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 Jan 17 at 12:29
Dmitry BychenkoDmitry Bychenko
107k1093133
107k1093133
I'm curious why(double)ff
is exactly31.14999961853027
and not31.150000000000000
– Gonzalo Lorieto
Jan 17 at 12:34
7
@Gonzalo Lorieto:double
is binary and0.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
add a comment |
I'm curious why(double)ff
is exactly31.14999961853027
and not31.150000000000000
– Gonzalo Lorieto
Jan 17 at 12:34
7
@Gonzalo Lorieto:double
is binary and0.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
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 Jan 17 at 13:02
answered Jan 17 at 12:41
BenBen
28.8k55588
28.8k55588
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
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