Implicitly converting int to double - c#

So, I'm a tad confused. I was under the impression that this should work:
In this case, both a and b are ints (Counters to be exact).
As the result of a / b may possibly contain decimal places, ints obviously won't work.
Therefore, I delared a new double and performed the calculation inside it like this:
double texturefactor = ((a / b) * 10);
This doesn't work as I expected, and the result of a / b is always that which I would get if I performed the calculation using an int to store the results.
On the other hand, this works:
double calculate1 = a;
double calculate2 = b;
double texturefactor = ((calculate1 / calculate2) * 10);
Couple of perhaps stupid questions-
1. I'm sure this ought to work- I know that in certain situations VS will complain that I've tried to implicitly convert from one type to another- That's what I'm trying to do! Why doesn't it, and have I missed something? :)
2. Should I just convert the counters a and b to doubles and save myself the trouble of the conversion, or is that trouble?

The result of a / b is another integer, so even if you do this, the damage has already been done:
double texturefactor = ((a / b) * 10);
Try casting one of your inner variables to a double:
var texturefactor = (( (double)a / b) * 10);
The result of (double)a / b will be a double, and you won't lose your fraction.
To answer your second question:
Should I just convert the counters a and b to doubles
That'd work too. If you change those to double, then you wouldn't have to perform the above cast.

The expression, including the types of subexpressions, is evaluated from inside to outside:
double texturefactor = ((a / b) * 10);
When the compiler analyses a / b, it has no idea that the result will later on be converted to double, so it just compiles the computation as an integer division.
Explicitly casting one of the two operands to double right there is enough to avoid that confusion:
double texturefactor = (((double)a / b) * 10);

When you have the expression (a / b), the C# compiler ignores that it will later be assigned to a double. It focuses only on that expression, and sees int / int, so it uses integer division. This means that your result is rounded down to the next integer before it's ever converted to a double.
You need to make sure C# treats the division as a division of doubles, not ints, for example:
double texturefactor = (((double)a / b) * 10); // or
double texturefactor = 10d * a / b; // or
double texturefactor = 10.0 * a / b;

The reason this double texturefactor = ((a / b) * 10); not working is that all the parameters on the right hand side are of type int thus the calculations are being done in int not double as you think.
You can explicitly cast a or b to double. Like
double texturefactor = (((double) a / b) * 10);
In your second code since you defined a and b as double, now the calculations are done in double type.

You need to cast the int values to double:
int a = some_value;
int b = some_value;
double texturefactor = (double)a / b * 10;

Integer division will not have decimal values just because you are assigning their values to a double variable.
If you want precision, then your second method is quite good.
double calculate1 = a;
double calculate2 = b;
double texturefactor = ((calculate1 / calculate2) * 10);
The above is good.
I will not advise you to cast it into double as there is some overhead to pay.

Result of dividing two integers is always a integer. So you need to
double texturefactor = (((double)a / b) * 10);

Therefore, I delared a new double and performed the calculation inside it like this:
Ah, no.
double texturefactor = ((a / b) * 10);
Basic syntax. YOu declare a double (texturefactor). You assign it the result of a pure integer opeation - (a/b)*10
Due to precedences this is a/b (integer, throw away digits) times 10. THEN implicit converison.
Typical beginner mistake - but one MANY do.
You want a double arithmetic, make sure any of the elements is a double, like for example:
((double) a/b)*10
will do a floating piont conversion for all elements.

Related

Why am I getting zero when I multiply doubles?

I made this line of code while debugging:
double hola = (1 / 2) * (double)x.height;
height is a double. Hola is just a temporary name.
When I debug, I see that x.height = 1, and hola = 0.
What did I do wrong? I'm pretty sure I made some really simple mistake..
Also when I remove the double casting that I do to x.height I still get hola = 0.
1 / 2 is zero, remainder one. Zero times anything is zero.
Did you mean to write 1.0 / 2.0?
1 and 2 are both int, so the result of 1/2 will be cast (truncated) to an int. 0.5 -> 0.
You need to make sure either of the operands supports decimal points:
double hola = (1.0 / 2) * (double)x.height;
Or:
double hola = ((double)1 / 2) * (double)x.height;
Dividing two integers will performs an integer division, which gives the result also in the same type(fractional part is truncated).Where a non-integer division(here double) on int arguments by explicitly casting at least one of the arguments to a double. So your code will be :
double hola = (1 / (double)2) * (double)x.height;
OR
double hola = ((double)1 / 2) * (double)x.height;

Implicit conversion/promotion of float or double in expressions between C# and Java

If I have the following expression:
byte A = 69;
int B = 123;
long C = 3210;
float D = 4.9f;
double E = 11.11;
double X = (B * 100) + 338.1 - (E / B) / C;
double X1 = (B * 100) + (A * D) - (E / B) / C;
// JAVA - lost precision
System.out.println(X); // 12638.099971861307
System.out.println(X1); // 12638.099581236307
// C# - almost the same
Console.WriteLine(X); // 12638.0999718613
Console.WriteLine(X1) // 12638.0999784417
I noticed that Java loses precision from X where 338.1 is implicit double while C# almost doesn't. I don't understand why because 338.1 is equals in float and in double. There is only one digit after the dot.
In Java, (B * 100) + (A * D) will be a float; and it will be the float that is closest to 12638.1. However, 12638 requires 14 digits to express in binary, including the initial 1; which leaves 10 digits of the significand to express the fractional part. Therefore, you're going to get the closest number of 1024ths to 0.1 - which is 102/1024. This turns out to be 0.099609375 - so the float has a rounding error of 0.000390625.
That seems to be the difference between X and X1 that you're getting in your Java program.
I'm afraid I'm not a C# expert, so I can't tell you why C# is different.
This has to do with the compilers interpretation of your expression. As you have not specified any intermediate type conversions, the compiler performs the A * D as first type conversion and then multiplication, instead of the reverse which you would expect. This might seem like a strange result, but it is a way for the compiler to give you a more exact result without you having to specify tedious type conversions.
Java does not handle this for you, and so (B * 100) + (A * D) is the multiplication of an int and a float - resulting in a float. This can be simulated in C# like this:
double X2 = (float)((B * 100) + (A * D)) - (E / B) / C;
Console.WriteLine("X2: {0}", X2);
This is one of the advantages (or dis-advantages some would probably say) of a high-level compiler.

Divide in C# with incorrect result [duplicate]

I'm currently writing a program that requires a preview of a live display, but the preview, of course, is scaled down. However, when I scale the PictureBox down, the size is incorrect. For the scale to be correct the width and height need to be at a 4:3 ratio. Here's the code:
private void FindOptimalRes(PictureBox picBox)
{
double h = Height / 4;
double ratio = 4 / 3;
picBox.Size = new Size((int)(h * ratio), (int)h);
}
In testing, Height (the height of the form) is 400, so, the width of the new size should be 133. But it always gets resized to 100×100! Why?
4 and 3 are both ints, so it gets turned to 1. Make them something floating-point:
double ratio = 4.0 / 3.0;
Note that you're also making the same mistake with Height (it doesn't matter right now, but it will - change it to 4.0). And if this is the actual code, why divide by four to multiply by four again?
private void FindOptimalRes(PictureBox picBox)
{
picBox.Size = new Size(Height / 3, Height / 4);
}
You are doing integer division:
double ratio = 4 / 3; // evaluates to 1
This won't give you the value you are looking for because the decimal point is being truncated, thus evaluating to 1 instead of 1.333. At least one of the operands needs to be a double:
double ratio = 4.0 / 3.0; // evaluates to 1.333
Same goes for Height. Change the 4 to 4.0.
C#'s math is "correct". The understanding of what is being done is .. missing :-)
The expression 4 / 3 (of type int / int) will evaluate to the integer value 1 as it is using integer division (both operands are integers). The resulting 1 is then implicitly coerced to a double value on assignment.
On the other hand 4d / 3 will "work" (and results in a double 1.333_) because now it is double / int -> double / double (by promotion) -> double using the appropriate floating point division.
Similarly, for Height / 4 (assuming Height is an integer), these would work:
(double)Height / 4 // double / int -> double
Height / 4d // int / double -> double
(double)Height / (double)4 // double / double -> double
Happy coding!
Make sure division result is double
double ratio = (double) 4 / 3; // double division
and no need to set your input values to double.
var num1 = // an integer number
var num2 = // an integer number
//result is integer, because of integer/integer uses 'integer division'
double result = num1 / num2;
//result is double , because of you forced to 'double division'
double result = (double) num1 / num2;
Maybe you should do a decimal division and not integer division:
double h = Height / 4.0;
double ratio = 4 / 3.0;
If C# Math was off many things around the world would be off as well.
You are doing integer division.
what you need to do is this :
private void FindOptimalRes(PictureBox picBox)
{
double h = Height / 4D; // or Height / 4.0
double ratio = 4D / 3D; // or 4.0 / 3.0
picBox.Size = new Size((int)(h * ratio), (int)h); // Size is now correct [133,100]
}
when you do a mathematical operation with an integer literal (no decimal places) it is implicitly typed as an int.
Simply appending a capital D at the end of your literals (4D, 3D) will type them as doubles, and your math will be correct. Alternatively you can write 4.0, 3.0

C# - Data Type for value 0.5

I have a calculation for example 2/4 = 0.5, except I can't find a data type that will store this value! Every time I make the calculation it says 0.
Anyone have any suggestions?
Either double or decimal will work fine.
However, if you just write:
// Wrong
double x = 2 / 4;
then it will still use integer division - because both of the operands for the division operator are of type int.
You can either cast either or both of the operands to double, or use a double literal for either or both of them:
// Any of these...
double x = (double) 2 / 4;
double x = 2 / (double) 4;
double x = (double) 2 / (double) 4;
double x = 2.0 / 4;
double x = 2 / 4.0;
double x = 2.0 / 4.0;
double x = 2d / 4;
double x = 2 / 4d;
double x = 2d / 4d;
Note that both double and decimal are floating point types. They don't represent arbitrary rational numbers (fractions). For example, neither can accurately represent 1/3. If you need a rational number type, you'll have to write your own or look for a third party implementation.
Make sure at least one of the divisor or the dividend is a floating number:
double d = 2 / 4.0;
Console.WriteLine(d): // Writes: 0.5
Use 2/4.0 to force it to use floating point arithmetics. Then you can store it in a double:
double d = 2/4.0;
If in the real code you have variables, cast the divisor to a double:
int i = 2;
int j = 4;
double d = i/(double)j;
You can cast,
double value = (double)2/4;
or you can provide your input with decimals
double value = 2.0/4.0;
Either float or double will do the job.
float x = 2f / 4f;
double x = 2d / 4d;
Note that you can specify constant values to be float or doubles by appending the appropriate character (f or d).
The important thing to remember is that the first data type (on the left) will determine the data type of the result. EDIT: actually, in this case either value being a float/double will work
So...
var x = 2 / 4;//x is int (0)
var x = 2f / 4;//x is float (0.5f)
var x 2d / 4;//x is double (0.5d)
C# will automatically convert int to float/double so...
float x = 2 / 4;//result type is int, but gets stored as convert float
Anyway, hope that helps explain some things

Why is modulus operator not working for double in 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);
}

Categories

Resources