The Question:
I am using Visual C# Express 2010. I am trying to divide three integers, however, the result is always 0.
My Code:
//earlier in the code:
int totalKeywords = 3;
//the problem code:
decimal onePercent = 100 / totalKeywords / 100; //100% divided by the number of keywords divided by 100 to make one percent
MessageBox.Show(onePercent);
//result: 0
//what I want: 0.33 or more acurate
What I've tried:
I've changed the value of totalKeywords
I've tried onePercent as a double, int, float, ect.
Guesses:
It could be that the built-in math doesn't work for some reason (WHY??)
It could be that decimal / int / float, etc. don't hold decimals (I don't think so)
My Efforts:
Google
Stack Overflow
C# high precision calculations
C# High double precision
etc.
Let's break it down:
decimal onePercent = 100 / totalKeywords / 100;
First, divide the integer literal 100 by the integer variable totalKeywords (value is 3). Result: integer 33.
Next, divide the result 33 by the integer literal 100. Result: integer 0.
The right-hand expression has type int, value 0. Convert that implicitly to the decmal 0m, so you can then assign that to the decimal variable onePercent.
Result: 0m.
To fix, as others have noticed, make the leftmost constant (if not all of them, for clarity) into a decimal. This will do, as the ints will implicitly convert to decimal:
decimal onePercent = 100m / totalKeywords / 100;
This is totally unambiguous, if a little over the top:
decimal onePercent = 100m / (decimal)totalKeywords / 100m;
try 100m / totalKeywords / 100
you have to define one of your numbers (at least) as decimal.
100 is an int
100m is a decimal
http://msdn.microsoft.com/en-us/library/364x0z75.aspx
If you want a numeric real literal to be treated as decimal, use the suffix m or M, for example:
decimal myMoney = 300.5m;
on right side after calculation you will get only integer, then it will be assigned to decimal, so it gives you 0.
Related
Here is the code which made me post this question.
// int integer;
// int fraction;
// double arg = 110.1;
this.integer = (int)(arg);
this.fraction = (int)((arg - this.integer) * 100);
The variable integer is getting 110. That's OK.
The variable fraction is getting 9, however I am expecting 10.
What is wrong?
Update
It seems I have discovered that the source of the problem is subtraction
arg - this.integer
Its result is 0.099999999999994316.
Now I am wondering how I should correctly subtract so that the result was 0.1.
You have this:
fraction = (int)((110.1 - 110) * 100);
The inner part ((110.1 - 110) * 100), will be 9.999999
When you cast it to int, it will be round off to 9
This is because of "floating point" (see here) limitations:
Computers always need some way of representing data, and ultimately
those representations will always boil down to binary (0s and 1s).
Integers are easy to represent, but non-integers are a bit more
tricky. Consider the following var:
double x = 0.1d;
The variable x will actually store the closest available double to
that value. When you understand this, it becomes obvious why some
calculations seem to be "wrong".
If you were asked to add a third to a third, but could only use 3
decimal places, you'd get the "wrong" answer: the closest you could
get to a third is 0.333, and adding two of those together gives 0.666,
rather than 0.667 (which is closer to the exact value of two thirds).
Update:
In financial applications or where the numbers are so important to be exact, you can use decimal data type:
(int)((110.1m - 110) * 100) //will be 10 (m is decimal symbol)
or:
decimal arg = 110.1m;
int integer = (int)(arg); //110
decimal fraction = (int)((arg - integer) * 100); //will be 10
It is because you are using double, precision gets rounded, if you want it to be 10 use decimal type:
check the following:
int integer;
int fraction;
decimal arg = 110.1M;
integer = (int)(arg);
decimal diff = arg - integer;
decimal multiply = diff * 100;
fraction = (int)multiply;//output will be 10 as you expect
When I'm trying to calculate a discount price, it returns 0 which is wrong.
The total is 100 and the percentage discount is 10%. I am sure about this formula, but it's keep returning 0.
My c# code :
protected void TxtDiscountPER_TextChanged(object sender, EventArgs e)
{
TxtDiscountAMT.Text = Convert.ToString(((Convert.ToInt16(TxtDiscountPER.Text)) / 100) * (Convert.ToInt16(TxtTotalAmt.Text)));
}
Here:
(Convert.ToInt16(TxtDiscountPER.Text)) / 100
you divide an Int16 (10) by an Int32 (100) using integer division, yielding 0. To quote from MSDN:
When you divide two integers, the result is always an integer. For example, the result of 7 / 3 is 2. To determine the remainder of 7 / 3, use the remainder operator (%). To obtain a quotient as a rational number or fraction, give the dividend or divisor type float or type double.
I suggest that you use the decimal data type instead of float or double, since decimal is better suited for monetary values:
(Convert.ToDecimal(TxtDiscountPER.Text)) / 100
The division will return a decimal value. You are converting the division to Int16. So it will always return an INT value which is 0
I'm trying to do a simple picee of maths where I work out if a value is between two values and if so, it does, it should do a simple division. However sometimes the value divided by are like 0.9, 0.6 etc and that always returns 0.
in this example,
int m_LocationSqrMtr = 4339;
float m_DefaultPricing = Convert.ToSingle(DefaultPricing);
float m_manDays;
if (m_LocationCosts > 450 && m_LocationCosts < 700)
{
m_DefaultPricing = 700 / m_LocationSqrMtr;
}
My guess is that the type of m_LocationSqrMtr is int, in which case this expression:
700 / m_LocationSqrMtr
... will be computed using integer arithmetic, and the result converted to float. I suspect you want:
if (m_LocationCosts > 450 && m_LocationCosts < 700)
{
m_DefaultPricing = 700f / m_LocationSqrMtr;
}
The f suffix on the literal means that it's a float literal, so first m_LocationSqrMtr will be promoted to float, and then the division performed using float arithmetic.
However, if this is meant to be representing currency values, you should consider using decimal instead of float - and then probably rounding the value to 2 decimal places. If you do all your currency arithmetic in decimal, you're less likely to run into unexpected results...
You have:
int m_LocationSqrMtr = 4339;
[...]
m_DefaultPricing = 700 / m_LocationSqrMtr;
That is, 700 / 4339, which is (integer) / (integer), the result of which is an integer.
I know you were expecting an answer of 0.16132....
But in integer terms, that value is ZERO.
If the type of m_LocationSqrMtr is int, as in a 32-bit whole number, then the expression
700 / m_LocationSqrMtr
is one integer divided by another integer, and it's type is integer. Only after this integer is produced is the result assigned to the float m_DefaultPricing, so basically your code is equivalent to:
int temp = 700 / m_LocationSqrMtr;
m_DefaultPricing = (float) temp;
If you want to force floating point arithmetic, at least one of the operands needs to be a floating point number. There are a number of ways that this can be done:
m_DefaultPricing = 700.0 / m_LocationSqrMtr; //explicit decimal point
m_DefaultPricing = 700f / m_LocationSqrMtr; //explicit float specification
m_DefaultPricing = (float)700 / m_LocationSqrMtr; //casting one operand
m_DefaultPricing = 700f / (float)m_LocationSqrMtr; //into a float
There are already a number of good practical answers so on a more conceptual level:
In C# if both sides of the operator are an integer the result is also an integer and any decimal digits are truncated. In general, for math, the language will produce a result of the same type as the input with the most precise type. The type of variable you store the result in will have no effect on the result only the types of the inputs.
By forcing one input to be decimal or float you force the output to be that as well. In practice you can either do this by declaring your one of your input variables as a decimal or float (depending on which you use, in your case you would change the type of m_LocationSqrMtr) or if you have a constant input (as you do) you can force it to be decimal/float/double as follows:
var a = 10f // float
var b = 10d // double
var c = 10m // decimal
var d = 10.0 // double I believe
This question already has answers here:
Why does integer division in C# return an integer and not a float?
(8 answers)
Closed 9 years ago.
Today i come with a problem and not able to figure out what is the issue with this simple statement
I Tried
double d =1/4;
expected ans for me is 0.25 but in reality ans is 0.0 why so ??
And what should we do if statement is in terms of integer variables like this
double a =(a-b)/(d+e);
Because what you done is here integer division. 1 / 4 always give you 0 as a result regardless which type you assing it.
.NET has 3 type of division. From 7.7.2 Division operator
Integer division
Floating-point division
Decimal division
From Integer division part;
The division rounds the result towards zero, and the absolute value of
the result is the largest possible integer that is less than the
absolute value of the quotient of the two operands.
If you want to 0.25 as a result, you should define one of your values as a floating point.
You can use one of these;
double d = 1d / 4d;
double d = 1d / 4;
double d = 1 / 4d;
And what should we do if statement is in terms of integer variables
like this
double a =(a-b)/(d+e);
I assume your a, b, d and e are integers, you should use one of these then;
double a = (double)(a-b) / (double)(d+e);
double a = (a-b) / (double)(d+e);
double a = (double)(a-b) / (d+e);
double d =1d/4;
should work.
If you don't specify the type of your numbers, it is treated as Integer. And integer 1/4 will be zero.
Use this:
double d = (double) 1 / 4;
/ Operator (msdn)
When you divide two integers, the result is always an integer. For
example, the result of 7 / 3 is 2. To determine the remainder of 7 /
3, use the remainder operator (%). To obtain a quotient as a rational
number or fraction, give the dividend or divisor type float or type
double. You can assign the type implicitly if you express the dividend
or divisor as a decimal by putting a digit to the right side of the
decimal point.
Try this:
double d = 1.0 / 4.0;
Given 2 values like so:
decimal a = 0.15m;
decimal b = 0.85m;
Where a + b will always be 1.0m, both values are only specified to 2 decimal places and both values are >= 0.0m and <= 1.0m
Is it guaranteed that x == total will always be true, for all possible Decimal values of x, a and b? Using the calculation below:
decimal x = 105.99m;
decimal total = (x * a) + (x * b);
Or are there cases where x == total only to 2 decimal places, but not beyond that?
Would it make any difference if a and b could be specified to unlimited decimal places (as much as Decimal allows), but as long as a + b = 1.0m still holds?
Decimal is stored as a sign, an integer, and an integer exponent for the number 10 that represents the decimal location. So long as your integral portion of the number (e.g. 105 in 105.99) is not sufficiently large, then a + b will always equal one. and the outcome of your equation (x * a) + (x * b) will always have the correct value for the four decimal places.
Unlike float and double, precision is not lost up to the size of the data type (128 bits)
From MSDN:
The Decimal value type represents decimal numbers ranging from
positive 79,228,162,514,264,337,593,543,950,335 to negative
79,228,162,514,264,337,593,543,950,335. The Decimal value type is
appropriate for financial calculations requiring large numbers of
significant integral and fractional digits and no round-off errors.
The Decimal type does not eliminate the need for rounding. Rather, it
minimizes errors due to rounding. For example, the following code
produces a result of 0.9999999999999999999999999999 rather than 1
decimal dividend = Decimal.One;
decimal divisor = 3;
// The following displays 0.9999999999999999999999999999 to the console
Console.WriteLine(dividend/divisor * divisor);
The maximum precision of decimal in the CLR is 29 significant digits. When you're using that kind of precision, you're really talking approximation especially if you do multiplication because that requires intermediate results that the CLR must be able to process (see also http://msdn.microsoft.com/en-us/library/364x0z75.aspx).
If you have x with 2 significant digits and, say, a with 20 significant digits, then x * a will already have a minimum precision of 22 digits, and possibly more may be needed for intermediate results.
If x always has only 2 significant digits and you can keep the number of significant digits in a and b low enough (say, 22 digits -- pretty good and probably far enough away from 27 to deal with rounding errors), then I suppose (x * a) + (x * b) should be a pretty precise calculation always.
Finally, whether a + b always makes up 1.0m is of no significance related to a and b's individual precisions.