This question already has answers here:
Why does floating-point arithmetic not give exact results when adding decimal fractions?
(31 answers)
Closed 5 years ago.
Look at this situation:
var number1 = Math.Floor(1.9999999999999998d); // the result is 1
var number2 = Math.Floor(1.9999999999999999d); // the result is 2
In a both cases, the result should be 1. I know it's a very unlikely scenario, but possible to occur. The same ocurr with Math.Truncate method and (int) cast.
Why does it happen?
There is no exact double representation for a lot of numbers.
The double number the nearest from 1.9999999999999999 is 2, so the compiler rounds it up.
Try to print it before using your Math.Floor function !
However, the nearest from 1.9999999999999998 is still 1.something, so Floor gives out 1 .
Again, it would be enough to print the number before the function Floorto see that they were actually not anymore the one entered in the code.
EDIT : To print out the number with most precision :
double a1 = 1.9999999999999998;
Console.WriteLine(a1.ToString("G17"));
// output : 1.9999999999999998
double a2 = 1.9999999999999999;
Console.WriteLine(a2.ToString("G17"));
// output : 2
Since double precision is not always precise to 17 significative digits (including the first one before the decimal point), default ToString() will round it up to 16 significant digits, thus, in this case, rounding it up to 2 as well, but only at runtime, not at compile time.
If you put literals values into another variables, then you see it why:
var a1 = 1.9999999999999998d; // a1 = 1.9999999999999998d
var number1 = Math.Floor(a1);
Console.WriteLine(number1); // 1
var a2 = 1.9999999999999999d; // a2 = 2
var number2 = Math.Floor(a2);
Console.WriteLine(number2); // 2
As for why - this has to be something to do with precision of double and decision of compiler as to what value to use for a given literal.
Related
I'm trying to figure out the name of the algorithm representing division operation as an array of integers you can summarize. Each element of this array must be as close to the actual rational result of the division as possible. For example:
5/2 = [3,2] (each element close to 2.5)
100/3 = [34,33,33] (each element close to 33.333(3))
3/1 = [3] (each element close to 3)
It seems like a very basic manipulation. The question is just out of sheer interest: is there a common name for such operation? Maybe it's already included in every math lib and I missed this fact?
Here's how I do it currently:
public IEnumerable<int> Distribute(int a, int b){
var div = a / b;
var rem = a % b;
return Enumerable.Repeat(div + 1, rem).Concat(Enumerable.Repeat(div, b - rem));
}
I think what you're looking for are the Math.Floor() and Math.Ceiling() functions. They can take a decimal number and return the highest (Math.Ceiling()) number and lowest (Math.Floor()) number closest to the decimal number given to those functions.
I have a scenario in which some variable values have decimal values, the values can have leading .0, .234, .124, .125, numbers like this, and so on. If the number has leading decimal and zero it should ignore and if a number has leading 3 or more numbers it should round off to two.
Let's say the code is as follows:
var anone = "23"
var antwo = "23.0"
var anthree = "23.467"
var anfour = "23.125"
In order to remove the leading decimal and zero I have used the following method:
var removingzero = antwo.Replace(".0", "");
// The result will be = 23
In order to round off and limit the number to two decimal points I have used the following method:
var convertodecimal = Decimal.Parse(anthree);
var roundtotwo = Math.Round(convertodecimal, 2);
// The result will be = 23.47
similarly in order to convert the last one I follow the same method:
var convertodecimal = Decimal.Parse(anfour);
var roundtotwo = Math.Round(convertodecimal, 2);
// The result will be = 23.12
// But the Result should be = 23.13
So, the problem is when I am trying to round off any number like the last example it does not do it, how can I fix it.
It sounds like your question is a long way of asking "How can I force rounding UP when a decimal number ends in 5?"
If that's the case, then you can use the overload of Math.Round that takes a MidpointRounding argument, and specify either MidpointRounding.AwayFromZero or MidpointRounding.ToPositiveInfinity.
The behavior of these is the same for positive numbers, but difference is seen with negative numbers, where -23.125 will round to -23.13 if AwayFromZero is specified, or -23.12 if ToPositiveInfinity is specified.
So your code might look like this instead:
var roundtotwo = Math.Round(convertodecimal, 2, MidpointRounding.AwayFromZero);
Try by changing your Math.Round() to below one:
Math.Round(num,2, MidpointRounding.AwayFromZero)
This question already has answers here:
How do you round a number to two decimal places in C#?
(15 answers)
Closed 8 years ago.
I want to get the round off value of a decimal number Suppose I am getting 24.86 than i want to get 25 as final value
Look at Math.Round(decimal) and the overload which accepts a MidpointRounding argument.
Simply
Math.Round(24.86)
This will round you value to 25.
Your own logic will be
decimal d = 1.5m;
decimal r = d - Math.Truncate(d);
if (r > 0)
r = 1 - r;
decimal value = d + r;
I am trying to round off each row to the nearest 1.0 in a column of a listview, so meaning 1.58 should show 2.00 and 1.48 should be 1.00 -
Math.Round(listView1.Columns[2].ToString(), 10);
You need to use 0 in digits parameter. You expect no digits here, but you're passing 10 to digit parameter which says to round with 10 digits after decimal.
var res = Math.Round(1.58, 0);//2
var res = Math.Round(1.48, 0);//1
Just saw you try to Round the string, You'll have to convert it to Double or decimal or whatever.
var rounded = Math.Round(Double.Parse(listView1.Columns[2].ToString()), 0);
In case you want to get String as a final result (as far as you've put ToString() in your code), you may just use appropriate formatting string ("F0" in your case):
String result = (1.58).ToString("F0"); // <- "2"
...
String result = (1.48).ToString("F0"); // <- "1"
You can't round a string directly.
string val=listView1.Columns[2].ToString();
double i;
if(Double.TryParse(val, out i))
{
Console.WriteLine(Math.Round(i)); // you can use Math.Round without second
// argument if you need rounding to the
// nearest unit
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to determine if a decimal/double is an integer?
I have a unique situation in which all numbers must be saved as double data type in my database, but only in certain conditions is the precision beyond the integer level valuable.
At first, I tried to just use int and then abstract to a new table when these unique fractional occurances would happen, but after doing that for weeks I can see now that it is excessively stupid and wasting my time.
I know that I can turn a double into an int. That is easy. I know how to translate it over. What I do not know is how to TEST for translating it over. I basically wish to come up with a short, easy way to say
Is this number really a double, or is it just an int?
If it is an int (and most of the time, it will be), then I will turn it into one and treat it as such. But due to the uniqueness of the requirements, I have to still save everything in the database as double.
Any ideas? I know this is a newbie question, and I've googled around for several hours and am still left quite confused.
Cast it to an int and see if it's still equal:
if ((int)val == val)
(int)val will truncate any fractional portion.
Note that this may behave unexpectedly if the number is too large to retain complete precision in the double.
double d = ...;
if(d == (int)d)
//is int
else
//is not int
Of course due to some precision issues, this may not work 100% times. You can use
double d = ...;
if(Math.Abs(d - (int)d) < Epsilon) //const double Epsilon = 0.000001;
//is int
else
//is not int
This similar post shows you how to determine if a double or decimal has decimal places or not. You can use this to determine what type it is and then store appropriately.
Accepted answer from that post:
For floating point numbers, n % 1 == 0 is typically the way to check if there is anything past the decimal point.
public static void Main (string[] args)
{
decimal d = 3.1M;
Console.WriteLine((d % 1) == 0);
d = 3.0M;
Console.WriteLine((d % 1) == 0);
}
Output:
False
True
try this
double x = ......
if (Math.truncate(x) == x)
....... (is integer, unless its so big its outside the bounds)