c# double - why is the answer always 0? [duplicate] - c#

This question already has answers here:
Why returns C# Convert.ToDouble(5/100) 0.0 and not 0.05
(7 answers)
Closed 8 years ago.
I have a double that when assigned is always coming back as 0.0, but should not happen.
The code I have is
double test = (27096140 / 27216140);
The answer to this should be 0.9955....
I am not using the double primitive type correctly?
Cheers
Edit
Of course, I was using int and no floating points.
Knew it would be a matter of common sense.

You are using integer division, you should use floating-point division:
double test = (27096140.0 / 27216140);

You are actually performing integer division here because the 2 numbers are whole. That forces the result of the calculation to be int which truncates the precision so you end up with 0.
You need to tell the compiler you are actually working with floating-point numbers and not int's, just adding a floating point to one of the numbers should fix this e.g.
double test = (27096140.0 / 27216140);
Alternatively, you could actually declare the numbers as doubles
double a = 27096140;
double b = 27216140;
double test = (a / b);
Or even cast the number in the calculation
double test = ((double)27096140 / 27216140)

Beacuse you're using integers instead of doubles. Use:
double test = (27096140.0d / 27216140.0d);

The numbers 27096140 and 27216140 are ints, so the result of the division is also an int: 0.
Then this is cast to a double: 0.0

Related

Why does this ulong divided by ulong give me 0? [duplicate]

This question already has answers here:
Why does integer division in C# return an integer and not a float?
(8 answers)
Closed 3 years ago.
I am grabbing total RAM of a computer system and available RAM and trying to work out what percentage is available.
I am using the following code:
double percent = my.Info.AvailablePhysicalMemory / my.Info.TotalPhysicalMemory;
and have also tried:
decimal percent = my.Info.AvailablePhysicalMemory / my.Info.TotalPhysicalMemory;
I am sure it's an issue with the type but I am unsure why both methods give a result of 0.
The actual values are Total: 17072574464 and Available: 8746000384. The values come back from the system cast as ulong. So what does percent always equal 0? If I put the numbers in directly it works fine. Just can't use the ulong variables - hence why I am sure it's my lack of experience with types in C# that is the problem.
You are trying to divide an integer by an integer, which always rounds down. You need to convert to a floating point number before you divide; for example:
double percent = my.Info.AvailablePhysicalMemory * 1.0 / my.Info.TotalPhysicalMemory;

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

This question already has answers here:
Is floating point math broken?
(31 answers)
Rounding of float values
(2 answers)
Difference between decimal, float and double in .NET?
(18 answers)
Closed 4 years ago.
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?
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
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.

Why does the decimal 2.5M round to 2? [duplicate]

This question already has answers here:
Why does Math.Round(2.5) return 2 instead of 3?
(15 answers)
Closed 6 years ago.
I must be missing some subtlety of .NET rounding. So I am looking at this example:
decimal num = 2.5M;
var result = Math.Round(num);
Why is result = 2? (I would have expected 3 since it should round up)
See MSDN:
Decimal Math.Round(Decimald)
Rounds a decimal value to the nearest integer, and rounds midpoint
values to the nearest even number (example).
"Midpoint" here means .5; the even number in your case is 2. If you rounded 3.5 this way, it would result in 4.
If you want to use "away from zero" rounding instead, you can use the System.MidpointRounding.AwayFromZero enum:
decimal d = 2.5M;
decimal roundedD = Math.Round(d, MidpointRounding.AwayFromZero); // results in 3
Regarding why it uses midpoint rounding (AKA "banker's rounding") by default instead of "away from zero" rounding, see this answer. Supposedly it's a better algorithm (i.e. more efficient over many iterations).
If you want classic rounding use
decimal num = 2.5M;
var result = Math.Round(num,0, MidpointRounding.AwayFromZero);
Please see https://msdn.microsoft.com/en-us/library/system.math.round(v=vs.110).aspx for details

c# calculation only returns natural number instead of decimal [duplicate]

When I make a division in C#, it automaticaly rounds down. See this example:
double i;
i = 200 / 3;
Messagebox.Show(i.ToString());
This shows me a messagebox containing "66". 200 / 3 is actually 66.66666~ however.
Is there a way I can avoid this rounding down and keep a number like 66.6666667?
i = 200 / 3 is performing integer division.
Try either:
i = (double)200 / 3
or
i = 200.0 / 3
or
i = 200d / 3
Declaring one of the constants as a double will cause the double division operator to be used.
200/3 is integer division, resulting in an integer.
try 200.0/3.0
200 / 3 this is an integer division. Change to: 200.0 / 3 to make it a floating point division.
You can specify format string with the desired number of decimal ponits:
double i;
i = 200 / 3.0;
Messagebox.Show(i.ToString("F6"));
Though the answer is actually 66.666, what is happening is that 200 / 3 is being calculated resulting in an integer. The integer is then being placed in the float. The math itself is happening as integer math. To make it a float, use 200.0 / 3. The .0 will cause it to treat 200 as a float, resulting in floating point math.
Aside from the double vs int happening in that action, you're thinking of double as a precise unit. Try using the decimal datatype when you really care about accuracy.
More information at this answer:
decimal vs double! - Which one should I use and when?
double i = 200.0 / 3;
double i = ((double)200)/3;
What happens is the two integers perform an integer divide, and then the integer answer is assigned to the float. To avoid that, always cast one of the numbers as a double.
Try this
i = 200d/3d;
and it will not round.
200 and 3 are both integers, so the result will be an integer. Convert one of them to a decimal.
All given answers are wrong because they translate the integer division into one of kind double, which is cleanly not what was asked for (at least from a performance standpoint). The obvious answer is elementary school math, multiply by 10, add 5 and divide again, all integer.
i = (2000 / 3 + 5 ) / 10
You are catching a second division here, which is better than doing double conversions but still far from perfect. You could go even further and multiply by another factor and add other values than five, thus allowing you to use right shifting instead of dividing by 10. The exact formula for doing this is left as an exercise to the reader. (Just google "divisions with Multiply Shift")
Have a nice day.

C# is rounding down divisions by itself

When I make a division in C#, it automaticaly rounds down. See this example:
double i;
i = 200 / 3;
Messagebox.Show(i.ToString());
This shows me a messagebox containing "66". 200 / 3 is actually 66.66666~ however.
Is there a way I can avoid this rounding down and keep a number like 66.6666667?
i = 200 / 3 is performing integer division.
Try either:
i = (double)200 / 3
or
i = 200.0 / 3
or
i = 200d / 3
Declaring one of the constants as a double will cause the double division operator to be used.
200/3 is integer division, resulting in an integer.
try 200.0/3.0
200 / 3 this is an integer division. Change to: 200.0 / 3 to make it a floating point division.
You can specify format string with the desired number of decimal ponits:
double i;
i = 200 / 3.0;
Messagebox.Show(i.ToString("F6"));
Though the answer is actually 66.666, what is happening is that 200 / 3 is being calculated resulting in an integer. The integer is then being placed in the float. The math itself is happening as integer math. To make it a float, use 200.0 / 3. The .0 will cause it to treat 200 as a float, resulting in floating point math.
Aside from the double vs int happening in that action, you're thinking of double as a precise unit. Try using the decimal datatype when you really care about accuracy.
More information at this answer:
decimal vs double! - Which one should I use and when?
double i = 200.0 / 3;
double i = ((double)200)/3;
What happens is the two integers perform an integer divide, and then the integer answer is assigned to the float. To avoid that, always cast one of the numbers as a double.
Try this
i = 200d/3d;
and it will not round.
200 and 3 are both integers, so the result will be an integer. Convert one of them to a decimal.
All given answers are wrong because they translate the integer division into one of kind double, which is cleanly not what was asked for (at least from a performance standpoint). The obvious answer is elementary school math, multiply by 10, add 5 and divide again, all integer.
i = (2000 / 3 + 5 ) / 10
You are catching a second division here, which is better than doing double conversions but still far from perfect. You could go even further and multiply by another factor and add other values than five, thus allowing you to use right shifting instead of dividing by 10. The exact formula for doing this is left as an exercise to the reader. (Just google "divisions with Multiply Shift")
Have a nice day.

Categories

Resources