I am using Math.Floor method to find out how many times can number a be in number b. In this concrete example, variables are with these values:
double a = 1.2;
double b = 0.1;
double c = Math.Floor(a / b) * b;
This returns c = 11 instead of c = 12 as I thought it will. I guess it has something to do with rounding, but how can I get it work properly? When I raise number a to 1,21, it returns 12.
double and float are internally represented in a way that lacks precision for many numbers, which means that a may not be exactly 1.2 (but, say, 1.199999999...) and b not exactly 0.1.
If you want exact precision, for quantities that do not have a margin of error like money, use decimal.
Have a look here for how Math.Floor works. ..basically , it rounds down ...
My guess would be that with doubles you don't really get 12 as the division (even though this will seems to work: double d = a/b; // d=12).
Solal pointed to the same, and gave a good advice about decimal :)
Here's what happens with decimals:
decimal a = 1.2m;
decimal b = 0.1m;
decimal c = Math.Floor(a / b) ; // c =12
The result of your code is 1.1.
I am assuming you want to get 1.2.
You need to use
double c = Math.Ceiling(a / b) * b;
Related
Is it save to compare the result of Math.Round(double,int) with == and use it for example as the key of a HashSet<Double> or a GroupBy(d=>Math.Round(d,1))?
In other words, are there any doubles x and y for which the following assertion will fail?
double x = ...;
double y = ...;
double xRound = Math.Round(x, 1);
double yRound = Math.Round(y, 1);
Debug.Assert(xRound==yRound || Math.Abs(xRound-yRound)>=0.1);
Let's say that I would like to group a list of doubles:
List<double> values = ...;
List<double> keys = values.GroupBy(d=>Math.Round(d,1)).Select(kv=>kv.Key).ToList();
Is there a chance that I would get a key with the value 0.100000000 and another key with the value 0.09999999999?
(I tried parsing the disassembled net framework Math.cs source, but Round() eventually calls a native function.)
Generally, given the same starting value and the same operations, the same result would be obtained.
However, if you (for example) did:
double d1 = 10;
d1 /= 0.1;
double d2 = 25;
d2 /= 0.25;
then you may well find that d1 and d2 do not have the same value (because IEEE754 can represent 0.25 exactly but not 0.1.
So, given that and the rather large number of issues people seem to have with floating point, I'd say your best bet would be to choose a different method of hashing.
I've got a very simple little program to solve quadratic equations, in the main it works but for some reason it won't calculate square roots. I just get an error saying NaN but I can't see how it's not a number?
int a = Convert.ToInt16(txta.Text);
int b = Convert.ToInt16(txtb.Text);
int c = Convert.ToInt16(txtc.Text);
listBox1.Items.Add(Convert.ToString(Math.Sqrt(((b * b) - (4 * a * c)))));
The conversions aren't the cause because if they didn't convert properly or if there was an overflow you'd get a FormatException or OverflowException respectively. None the less, since you're doing math you might want to convert to double types.
double a = Convert.ToDouble(txta.Text);
double b = Convert.ToDouble(txtb.Text);
double c = Convert.ToDouble(txtc.Text);
I believe your expression: (b * b) - (4 * a * c) is the problem. If it evaluates to a negative number, that will result in a NaN result.
See Math.Sqrt Method on MSDN for more information.
It's likely getting a negative number. It might help to convert it to a double instead of an Int16, because Int16 will round every time.
Suppose I have three doubles, a, b and c.
double a = 1.234560123;
double b = 7.890120123;
double c = a * b;
c = 9.740827669535655129
I want to work with numbers with only 5 decimal places. So if I round a and b using Math.Round(a, 5) and Math.Round(b, 5) I get:
double a_r = Math.Round(a, 5);
double b_r = Math.Round(b, 5);
a_r = 1.23456
b_r = 7.89012
double c_r = a_r * b_r;
c_r = 9.7408265472
But when I calculate c, I still get a number with more than 5 decimal places (this will happen in every multiplication, division, potentiation and similar operations). I could round all results in my code, but that's hard work that I want to avoid.
As I use c in other operations and the results of this operations in other ones, I don't want to round all the intermediate results every time to not propagate the error caused by undesired decimal places.
Is there a way to define doubles with a fixed number of decimal places, independently of the operation?
Typically, it's best to leave the doubles in place, and use the custom formatting to display the values to 5 decimal points:
double a = 1.234560123;
double b = 7.890120123;
double c = a * b;
Console.WriteLine("Result = {0:N5}", c);
Nearly all routines that convert numeric values into strings allow the use of the Standard Numeric Format Strings as well as Custom Numeric Format Strings.
You canĀ“t define a double with limited decimal places. You should rely on formatting the number when you display it. See this question
I found a way to solve my problem using Operator Overload.
So I re-defined all my operations as multiplication, division, complex multiplication and matrices operations to round the result to the number of decimal places I wanted.
An example:
public static double operator *(double d1, double d2)
{
double result;
result = Math.Round(d1 * d2, 5);
return result;
}
I have the following code :
double a = 8/ 3;
Response.Write(a);
It returns the value 2. Why? I need at least one decimal digit. Something like 2.6, or 2.66. How can I get such results?
Try
double a = 8/3.0d;
or
double a = 8.0d/3;
to get a precise answer.
Since in expression a = 8/3 both the operands are int so the result is int irrespective of the fact that it is being stored in a double. The results are always in the higher data type of operands
EDIT
To answer
8 and 3 are get from variable. Can I do a sort of cast?
In case the values are coming from a variable you can cast one of the operands into double like:
int b = 8;
int c = 3;
double a = ((double) b) /c;
Because the calculation are being done in integer type not double. To make it double use:
double a = 8d/ 3d;
Response.Write(a);
Or
double a = 8.0/ 3.0;
Response.Write(a);
One of your operands should be explicitly marked as double either by using d or specifying a decimal point 0
or if you need you can cast them to double before the calculations. You can cast either one or both operands to double.
double a = ((double) 8)/((double)3)
because 8 and 3 are integer numbers and interpreter rounds it to 2.
You can simply advise to interpreter that you numbers are floating numbers:
double a = (double)8 / 3;
Because its making a rounding towards minus, its the way its implemented in the framework. However if you specify the precision by using the above example:
double a = 8/3.0d;
then rounding is no longer performed.
Or in simple terms you assigned an integer value to a double, thats why the rounding was performed in the first place. It saw an operation with integers.
Coz 8 and 3 both ints. And int's division operator with two ints in it returns int as well. (F12 when the cursor is on slash sign).
I have this:
double result = 60 / 23;
In my program, the result is 2, but correct is 2,608695652173913. Where is problem?
60 and 23 are integer literals so you are doing integer division and then assigning to a double. The result of the integer division is 2.
Try
double result = 60.0 / 23.0;
Or equivalently
double result = 60d / 23d;
Where the d suffix informs the complier that you meant to write a double literal.
You can use any of the following all will give 2.60869565217391:
double result = 60 / 23d;
double result = 60d / 23;
double result = 60d/ 23d;
double result = 60.0 / 23.0;
But
double result = 60 / 23; //give 2
Explanation:
if any of the number is double it will give a double
EDIT:
Documentation
The evaluation of the expression is performed according to the following rules:
If one of the floating-point types is double, the expression evaluates to double (or bool in the case of relational or Boolean expressions).
If there is no double type in the expression, it evaluates to float (or bool in the case of relational or Boolean expressions).
It will work
double result = (double)60 / (double) 23;
Or equivalently
double result = (double)60 / 23;
(double) 60 / 23
Haven't used C# for a while, but you are dividing two integers, which as far as I remember makes the result an integer as well.
You can force your number literals to be doubles by adding the letter "d", likes this:
double result = 60d / 23d;
double result = 60.0 / 23.0;
It is best practice to correctly decorate numerals for their appropriate type. This avoids not only the bug you are experiencing, but makes the code more readable and maintainable.
double x = 100d;
single x = 100f;
decimal x = 100m;
convert the dividend and divisor into double values, so that result is double
double res= 60d/23d;
To add to what has been said so far... 60/23 is an operation on two constants. The compiler recognizes the result as a constant and pre-computes the answer. Since the operation is on two integers, the compiler uses an integer result The integer operation of 60/23 has a result of 2; so the compiler effective creates the following code:
double result = 2;
As has been pointed out already, you need to tell the compiler not to use integers, changing one or both of the operands to non-integer will get the compiler to use a floating-point constant.