Why result of % operator for double differ from decimal? [duplicate] - c#

Consider this:
double x,y;
x =120.0;
y = 0.05;
double z= x % y;
I tried this and expected the result to be 0, but it came out 0.04933333.
However,
x =120.0;
y = 0.5;
double z= x % y;
did indeed gave the correct result of 0.
What is happening here?
I tried Math.IEEERemainder(double, double) but it's not returning 0 either. What is going on here?
Also, as an aside, what is the most appropriate way to find remainder in C#?

Because of its storage format, doubles cannot store every values exactly as is is entered or displayed. The human representation of numbers is usually in decimal format, while doubles are based on the dual system.
In a double, 120 is stored precisely because it's an integer value. But 0.05 is not. The double is approximated to the closest number to 0.05 it can represent. 0.5 is a power of 2 (1/2), so it can be stored precisely and you don't get a rounding error.
To have all numbers exactly the same way you enter / display it in the decimal system, use decimal instead.
decimal x, y;
x = 120.0M;
y = 0.05M;
decimal z = x % y; // z is 0

You could do something like:
double a, b, r;
a = 120;
b = .05;
r = a - Math.floor(a / b) * b;
This should help ;)

I believe if you tried the same with decimal it would work properly.

http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems can help you understand why you get these "strange" results. There's a particular precision that floating point numbers can have. Just try these queries and have a look at the results:
0.5 in base 2
0.05 in base 2

Modulus should only be used with integer. The remainder come from an euclidean division. With double, you can have unexpected results.
See this article

This is what we use.. :)
public double ModuloOf(double v1, double v2)
{
var mult = 0;
//find number of decimals
while (v2 % 1 > 0)
{
mult++;
v2 = v2 * 10;
}
v1 = v1 * Math.Pow(10, mult);
var rem = v1 % v2;
return rem / Math.Pow(10, mult);
}

Related

changing celsius to fahrenheit and vice versa in c# [duplicate]

This simple calculation is returning zero, I can't figure it out:
decimal share = (18 / 58) * 100;
You are working with integers here. Try using decimals for all the numbers in your calculation.
decimal share = (18m / 58m) * 100m;
18 / 58 is an integer division, which results in 0.
If you want decimal division, you need to use decimal literals:
decimal share = (18m / 58m) * 100m;
Since some people are linking to this from pretty much any thread where the calculation result is a 0, I am adding this as a solution as not all the other answers apply to case scenarios.
The concept of needing to do calculations on various types in order to obtain that type as a result applies, however above only shows 'decimal' and uses it's short form such as 18m as one of the variables to be calculated.
// declare and define initial variables.
int x = 0;
int y = 100;
// set the value of 'x'
x = 44;
// Results in 0 as the whole number 44 over the whole number 100 is a
// fraction less than 1, and thus is 0.
Console.WriteLine( (x / y).ToString() );
// Results in 0 as the whole number 44 over the whole number 100 is a
// fraction less than 1, and thus is 0. The conversion to double happens
// after the calculation has been completed, so technically this results
// in 0.0
Console.WriteLine( ((double)(x / y)).ToString() );
// Results in 0.44 as the variables are cast prior to calculating
// into double which allows for fractions less than 1.
Console.WriteLine( ((double)x / (double)y).ToString() );
Because the numbers are integers and you perform integer division.
18 / 58 is 0 in integer division.
Whenever I encounter such situations, I just upcast the numerator.
double x = 12.0 / 23409;
decimal y = 12m / 24309;
Console.WriteLine($"x = {x} y = {y}");
double res= (firstIntVar * 100f / secondIntVar) / 100f;
when dividing numbers I use double or decimal , else I am getting 0 , with this code even if firstIntVar && secondIntVar are int it will return the expected answer
decimal share = (18 * 100)/58;
Solved: working perfectly with me
int a = 375;
int b = 699;
decimal ab = (decimal)a / b * 100;

Why is x 1 when assigning a double?

I'm very new with C#.
I don't understand why is x = 1 and not 1.4.
Can please somebody explain me this?
double x = (double)(12 / 5 - 3 % 2);
Console.WriteLine(x);
Because this is NOT about double.
You are integer-executing
(12 / 5 - 3 % 2);
and THEN casting to double. If you want this to be about double, then make sure at least one of the numbers is a double. In your case just mark the literals as double.
(12d / 5d - 3d % 2d);
is all doubles. As long as one is a double, the operation happens as double - but your original case makes all the calculations, THEN casts to double. So they happen as integer.
You're doing integer math and then converting to double. 12 / 5 = 2, 3 % 2 = 1, and 2 - 1 = 1.
Welcome to stackoverflow! :)
The problem is that you are operating all int, and afterwards converting them to double.
You need to make sure that you are operating with doubles from the beginning.
Try out the code in here: https://dotnetfiddle.net/xaQjKL
using System;
public class Program
{
public static void Main()
{
// Doubles from the beggining
double d_twelve = 12.0;
double d_five = 5.0;
double x = (double)(d_twelve / d_five);
Console.WriteLine($"Using all doubles: {x}");
// First split two int, then convert the result to double
int i_twelve = 12;
int i_five = 5;
x = (double)(i_twelve / i_five);
Console.WriteLine($"Using ints, and converting at the end to double: {x}");
// And now your code:
x = (double)(12 / 5 - 3 % 2);
Console.WriteLine($"Your original code: {x}");
// And now your code fixed (notice the 12 => 12.0):
x = (double)(12.0 / 5 - 3 % 2);
Console.WriteLine($"Changing 12 by 12.0: {x}");
}
}
You are doing operations with integers and then casting he result to a double.
double x = (12d / 5d - 3d % 2d);
Console.WriteLine(x);
Adding d after a number will make it a double while adding f will make it a float.
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/floating-point-numeric-types#real-literals
Because you use integer values inside the parenthesis, and the expression is calculated using integer math before being cast to double.
You can use a double value for the first value and it should be enough:
> double x = (12d / 5) - (3 % 2);
> Console.WriteLine(x);
1.4

Lamda expression not working on String.Count() [duplicate]

This simple calculation is returning zero, I can't figure it out:
decimal share = (18 / 58) * 100;
You are working with integers here. Try using decimals for all the numbers in your calculation.
decimal share = (18m / 58m) * 100m;
18 / 58 is an integer division, which results in 0.
If you want decimal division, you need to use decimal literals:
decimal share = (18m / 58m) * 100m;
Since some people are linking to this from pretty much any thread where the calculation result is a 0, I am adding this as a solution as not all the other answers apply to case scenarios.
The concept of needing to do calculations on various types in order to obtain that type as a result applies, however above only shows 'decimal' and uses it's short form such as 18m as one of the variables to be calculated.
// declare and define initial variables.
int x = 0;
int y = 100;
// set the value of 'x'
x = 44;
// Results in 0 as the whole number 44 over the whole number 100 is a
// fraction less than 1, and thus is 0.
Console.WriteLine( (x / y).ToString() );
// Results in 0 as the whole number 44 over the whole number 100 is a
// fraction less than 1, and thus is 0. The conversion to double happens
// after the calculation has been completed, so technically this results
// in 0.0
Console.WriteLine( ((double)(x / y)).ToString() );
// Results in 0.44 as the variables are cast prior to calculating
// into double which allows for fractions less than 1.
Console.WriteLine( ((double)x / (double)y).ToString() );
Because the numbers are integers and you perform integer division.
18 / 58 is 0 in integer division.
Whenever I encounter such situations, I just upcast the numerator.
double x = 12.0 / 23409;
decimal y = 12m / 24309;
Console.WriteLine($"x = {x} y = {y}");
double res= (firstIntVar * 100f / secondIntVar) / 100f;
when dividing numbers I use double or decimal , else I am getting 0 , with this code even if firstIntVar && secondIntVar are int it will return the expected answer
decimal share = (18 * 100)/58;
Solved: working perfectly with me
int a = 375;
int b = 699;
decimal ab = (decimal)a / b * 100;

basic maths calculations in c# [duplicate]

This simple calculation is returning zero, I can't figure it out:
decimal share = (18 / 58) * 100;
You are working with integers here. Try using decimals for all the numbers in your calculation.
decimal share = (18m / 58m) * 100m;
18 / 58 is an integer division, which results in 0.
If you want decimal division, you need to use decimal literals:
decimal share = (18m / 58m) * 100m;
Since some people are linking to this from pretty much any thread where the calculation result is a 0, I am adding this as a solution as not all the other answers apply to case scenarios.
The concept of needing to do calculations on various types in order to obtain that type as a result applies, however above only shows 'decimal' and uses it's short form such as 18m as one of the variables to be calculated.
// declare and define initial variables.
int x = 0;
int y = 100;
// set the value of 'x'
x = 44;
// Results in 0 as the whole number 44 over the whole number 100 is a
// fraction less than 1, and thus is 0.
Console.WriteLine( (x / y).ToString() );
// Results in 0 as the whole number 44 over the whole number 100 is a
// fraction less than 1, and thus is 0. The conversion to double happens
// after the calculation has been completed, so technically this results
// in 0.0
Console.WriteLine( ((double)(x / y)).ToString() );
// Results in 0.44 as the variables are cast prior to calculating
// into double which allows for fractions less than 1.
Console.WriteLine( ((double)x / (double)y).ToString() );
Because the numbers are integers and you perform integer division.
18 / 58 is 0 in integer division.
Whenever I encounter such situations, I just upcast the numerator.
double x = 12.0 / 23409;
decimal y = 12m / 24309;
Console.WriteLine($"x = {x} y = {y}");
double res= (firstIntVar * 100f / secondIntVar) / 100f;
when dividing numbers I use double or decimal , else I am getting 0 , with this code even if firstIntVar && secondIntVar are int it will return the expected answer
decimal share = (18 * 100)/58;
Solved: working perfectly with me
int a = 375;
int b = 699;
decimal ab = (decimal)a / b * 100;

Rounding up to 2 decimal places in C#

I have a decimal number which can be like the following:
189.182
I want to round this up to 2 decimal places, so the output would be the following:
189.19
Is there built in functionality for this in the Math class, or something else? I know the ceiling function exists but this doesn't seem to do what I want - it'll round to the nearest int, so just '189' in this case.
Multiply by 100, call ceiling, divide by 100 does what I think you are asking for
public static double RoundUp(double input, int places)
{
double multiplier = Math.Pow(10, Convert.ToDouble(places));
return Math.Ceiling(input * multiplier) / multiplier;
}
Usage would look like:
RoundUp(189.182, 2);
This works by shifting the decimal point right 2 places (so it is to the right of the last 8) then performing the ceiling operation, then shifting the decimal point back to its original position.
You can use:
decimal n = 189.182M;
n = System.Math.Ceiling (n * 100) / 100;
An explanation of the various rounding functions can be found here.
Be aware that formulae like this are still constrained by the limited precision of the double type, should that be the type you are using (your question stated decimal but it's possible you may just have meant a floating point value with fractional component rather than that specific type).
For example:
double n = 283.79;
n = System.Math.Ceiling (n * 100);
will actually give you 28380, not the 283.79 you would expect(a).
If you want accuarate results across the board, you should definitely be using the decimal type.
(a) This is because the most accurate IEEE754 double precision representation of 283.79 is actually:
283.790000000000020463630789891
That extra (admittedly minuscule) fractional component beyond the .79 gets ceilinged up, meaning it will give you a value higher than you would expect.
var numberToBeRound1 = 4.125;
var numberToBeRound2 = 4.175;
var numberToBeRound3 = 4.631;
var numberToBeRound4 = 4.638;
var numberOfDecimalPlaces = 2;
var multiplier = Math.Pow(10, numberOfDecimalPlaces);
//To Round Up => 4.13
var roundedUpNumber = Math.Ceiling(numberToBeRound1 * multiplier) / multiplier;
//To Round Down => 4.12
var roundedDownNumber = Math.Floor(numberToBeRound1 * multiplier) / multiplier;
//To Round To Even => 4.12
var roundedDownToEvenNumber = Math.Round(numberToBeRound1, numberOfDecimalPlaces, MidpointRounding.ToEven);
//To Round To Even => 4.18
var roundedUpToEvenNumber = Math.Round(numberToBeRound2, numberOfDecimalPlaces, MidpointRounding.ToEven);
//To Round To Away From Zero => 4.63
var roundedDownToAwayFromZero = Math.Round(numberToBeRound3, numberOfDecimalPlaces, MidpointRounding.AwayFromZero);
//To Round To Away From Zero => 4.64
var roundedUpToAwayFromZero2 = Math.Round(numberToBeRound4, numberOfDecimalPlaces, MidpointRounding.AwayFromZero);
How about
0.01 * ceil(100 * 189.182)
In .NET Core 3.0 and later versions, three additional rounding strategies are available through the MidpointRounding enumeration.
Besides MidpointRounding.AwayFromZero and MidpointRounding.ToEven it now includes:
1. MidpointRounding.ToNegativeInfinity
2. MidpointRounding.ToPositiveInfinity
3. MidpointRounding.ToZero
For this specific question you need to use MidpointRounding.ToPositiveInfinity, this will round the number up always.
Note this only works if the number isn't negative. See table below for examples.
Original number
ToNegativeInfinity
ToPositiveInfinity
ToZero
3.55
3.5
3.6
3.5
2.83
2.8
2.9
2.8
2.54
2.5
2.6
2.5
2.16
2.1
2.2
2.1
-2.16
-2.2
-2.1
-2.1
-2.54
-2.6
-2.5
-2.5
-2.83
-2.9
-2.8
-2.8
-3.55
-3.6
-3.5
-3.5
For more information about midpointrounding see https://learn.microsoft.com/en-us/dotnet/api/system.midpointrounding
And of course the code to make it work:
// function explained: Math.Round(number, amount of decimals, MidpointRounding);
decimal number = 189.182m;
number = Math.Round(number, 2, MidpointRounding.ToPositiveInfinity);
// result: number = 189.19
public static decimal RoundUp(decimal input, int places)
{
decimal multiplier = (decimal)Math.Pow(10, places);
return decimal.Ceiling(input * multiplier) / multiplier;
}
// Double will return the wrong value for some cases. eg: 160.80
public static decimal RoundUp(decimal input, int places)
{
decimal multiplier = Convert.ToDecimal(Math.Pow(10, Convert.ToDouble(places)));
return Math.Ceiling(input * multiplier) / multiplier;
}
One other quirky but fun way to do it is Math.Round() after offsetting the number.
decimal RoundUp(decimal n, int decimals)
{
n += decimal.Parse($"1e-{decimals}", System.Globalization.NumberStyles.AllowExponent) / 2;
n -= 1e-28m;
return Math.Round(n, decimals);
}
decimal RoundDown(decimal n, int decimals)
{
n -= decimal.Parse($"1e-{decimals}", System.Globalization.NumberStyles.AllowExponent) / 2;
n += 1e-28m;
return Math.Round(n, decimals);
}
Is has the advantage of not using Math.Pow() which uses double and thus can cause unpredictable rounding errors.
This solution basically uses the fact that midpoint rounding can be turned into up/down rounding if you increase/decrease the number a little:
Math.Round(3.04m, 1) is 3.0 - not what we want
Let's add 0.04(9) to it
Math.Round(3.0899999999999999999999999999m, 1) is 3.1 - success!
Subtracting 1e-28m (= 0.0000000000000000000000000001) is important, because we want to be able to round up 3.0000000000000000000000000001 to 4, but 3.0000000000000000000000000000 should stay 3.

Categories