Why does this result in 0 and upsidedown not? - c#

Currently I am writing my thesis and I was confronted with a behavior of .Net C# that I had never seen before. I am talking about an error in a calculation.
I implemented this formula:
1/2 * (Theta i-1 + Theta i) + Sum(Alph k, k=1, i-1)
This formula is applied to 4 objects. Theta is in all objects declared as float with the value 1,5708. Alpha is initialized with 0 and will be increased by each iteration.
First implmentation
float alpha = 0;
float value = 0;
for (int sphereCount = 1; sphereCount < this.spheres.Count; sphereCount++)
{
value = (1/2) * (this.spheres[sphereCount - 1].Theta + this.spheres[sphereCount].Theta);
alpha += value;
}
With this version value is always 0.0!
So I changed it to:
Working implementaion
float alpha = 0;
float value = 0;
for (int sphereCount = 1; sphereCount < this.spheres.Count; sphereCount++)
{
value =(this.spheres[sphereCount - 1].Theta + this.spheres[sphereCount].Theta) * 1/2;
alpha += value;
}
By removing the brackets around the 1/2 and placing it at the end of the calculation it worked.
WHY IS THAT SO???
It seems when you place 1/2 in brackets not depending on the position of 1/2 the result is 0.0. But also when i place (1/2) at the end it results in 0.0.
Does anyone here have an idea why?

This
(1 / 2)
evaluates to 0 because it's integer division. If you say
(1 / 2f)
or
(1 / (float) 2)
you'll be fine because it forces float divsion. Or, even better, just write 0.5.

If you write 1/2 the result is calculated using integer division that gives an integer result. You can force a floating point division by changing one of the numbers to a floating point number, as in 1/2f.
Or you could just write 0.5 which IMHO is more readable than 1/2.

Why multiply by 1? Rather than this:
value =(this.spheres[sphereCount - 1].Theta + this.spheres[sphereCount].Theta) * 1/2;
why not write this:
value =(this.spheres[sphereCount - 1].Theta + this.spheres[sphereCount].Theta) / 2;

You should write 1.0/2 or 0.5 instead 1/2.
1/2 is an integer division which results in an integer 0.

Because 1/2 is treated as integer arithmetic and as such is rounded to 0.
Removing the parenthesis changes the order of operations, and now you are dividing your whole (floating point) formula by two and arriving at a floating point answer.

That's because 1 and 2 are integer values, not floating point values.
When you divide the integer value 1 by the integer value 2, the result is the integer value 0, not the floating point value 0.5.
When you remove the parentheses and change the order of the multiplication, the other part of the expression will first be multiplied by 1, which will implicitly convert the integer value 1 into a floating point value. Then the result is divided by 2, which will also be implicitly converted into a floating point value.
So what you end up doing is:
value = ( (this.spheres[sphereCount - 1].Theta + this.spheres[sphereCount].Theta) * (float)1 ) / (float)2;

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;

Arithmetic operation is always evaluated as 0

I'm working on a flocking algorithm and for this I need to have an algrithm for the cohesive force. For this I'm using this line:
velocityVector.X = 10 / (distX - distanceBetweenLabels)
* (label.Location.X - ctrl.Location.X);
After this line velocitVector.X always equals 0. The distX is always positive. My aim for this is to produce nice cohesion between the particles while still keeping a minimum distance between them.
UPDATE
So thanks for the comments the 10 / (distX - distanceBetweenLabels) was defaulting to integer caluclation hence equating the whole line to 0.
10 / (distX - distanceBetweenLabels)
* (label.Location.X - ctrl.Location.X);
10 here keeps the expression integer if the denominator turns out to be integer.
Change it to 10.0 or better 10F for float of 10D for double precision .
Evaluating the following :
var intTest = 10/123;
var floatTest = 10F/123;
var doubleTest = 10D/123;
Outputs as :
0
0.08130081
0.0813008130081301

Cant seem to compute normal distribution

I have interprated the formula in wikipedia in c# code, i do get a nice normal curve, but is it rational to get values that exceeds 1? isnt it suppose to be a distribution function?
this is the C# implementation :
double up = Math.Exp(-Math.Pow(x , 2) / ( 2 * s * s ));
double down = ( s * Math.Sqrt(2 * Math.PI) );
return up / down;
i double checked it several times and it seems fine to me so whats wrong? my implementation or understanding?
for example if we define x=0 and s=0.1 this impl would return 3.989...
A distribution function, a pdf, has the property that its values are >= 0 and the integral of the pdf over -inf to +inf must be 1. But the integrand, that is the pdf, can take any value >= 0, including values greater than 1.
In other words, there is no reason, a priori, to believe that a pdf value > 1 indicates a problem.
You can think about this for the normal curve by considering what reducing the variance means. Smaller variance values concentrate the probability mass in the centre. Given that the total mass is always one, as the mass concentrates in the centre, the peak value must increase. You can see that trend in the graph the you link to.
What you should do is compare the output of your code with known good implementations. For instance, Wolfram Alpha gives the same value as you quote: http://www.wolframalpha.com/input/?i=normal+distribution+pdf+mean%3D0+standard+deviation%3D0.1+x%3D0&x=6&y=7
Do a little more testing of this nature, captured in a unit test, and you will be able to rely on your code with confidence.
Wouldn't you want something more like this?
public static double NormalDistribution(double value)
{
return (1 / Math.Sqrt(2 * Math.PI)) * Math.Exp(-Math.Pow(value, 2) / 2);
}
Yes, it's totally OK; The distribution itself (PDF) can be anything from 0 to +infinity; the thing should be in the range [0..1] is the corresponding integral(s) (e.g. CDF).
You can convince yourself if look at the case of non-random value: if the value is not a random at all and can have only one constant value the distribution degenerates (standard error is zero, mean is the value) into Dirac Delta Function: a peak of infinite hight but of zero width; integral however (CDF) from -infinity to +infinity is 1.
// If you have special functions implemented (i.e. Erf)
// outcoume is in [0..inf) range
public static Double NormalPDF(Double value, Double mean, Double sigma) {
Double v = (value - mean) / sigma;
return Math.Exp(-v * v / 2.0) / (sigma * Math.Sqrt(Math.PI * 2));
}
// outcome is in [0..1] range
public static Double NormalCDF(Double value, Double mean, Double sigma, Boolean isTwoTail) {
if (isTwoTail)
value = 1.0 - (1.0 - value) / 2.0;
//TODO: You should have Erf implemented
return 0.5 + Erf((value - mean) / (Math.Sqrt(2) * sigma)) / 2.0;
}

When incrementing a double value in a for loop, how can I make sure it stays relatively round?

I have this for loop:
for (double x = -1 * (display.Width / zoom); x <= (display.Width / zoom); x += 0.1)
{
//..
}
x is initialized to -20 and is compared against 20. Ideally, I would like x to be incremented as -20, -19.9, -19.8, etc. In practice, this is not what happens; on some iterations, there is indeed only one digit after the decimal point, but in others, it is not as precise, for example -19.8999999. This is responsible for some very irritating (and hard to find) bugs in my program.
How can I make it so that x stays 'relatively round'?
Don't use double or float if you need this kind of accuracy - use decimal instead.
This is happening because certain fractions cannot be accurately represented in binary - I suggest reading What Every Computer Scientist Should Know About Floating-Point Arithmetic.
This has to do with the way a double is stored. Try a decimal instead.
Use integer loop counter, initialized to -200 and compared against 200, and calculate your real x in each iteration.
UPD: using Decimal is probably better.
If i understand you right... why you just round it?
Math.Round(x,1)
Floating point numbers (Double/Float) aren't accurate, instead use -200 and 200 as an int. That will allow to not have to worry about lack of floating point precision.
For more information about this imprecision, I suggest this document.
http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
IF you really want it as precise as possible scale it up so that you can work with int or long... for example:
long _Z = (long) ((display.Width * 10) / zoom);
for (long _x = -1 * _Z; _x <= _Z; _x += 1)
{
double x = ((double)_x) / 10.0;
// ...
}
if you must use double you could use like this:
double x = 0.0;
while (x <= 3.0)
{
//Do your stuff
x = Math.Round(x + 0.1, 1);
}

Annoying double value

Ok can anyone explain why the variable offset comes back as 0?
I need to update a progress bar but the value is less than 100 so offset is the value to increase current by and then update the progress bar with the floored value of current but as it comes back 0 it's not updating!
double offset = 0.000001;
int hmm = (image.Height * image.Width);
double current = 0;
MessageBox.Show(offset.ToString());
MessageBox.Show(hmm.ToString());
offset = 100 / hmm;// 0.01;// 100 / (image.Height * image.Width) * 10000;
MessageBox.Show(offset.ToString());
You're performing integer division - both hmm and 100 are integers. Therefore if hmm is greater than 100, it will always give 0 as the result. Convert either operand to a double and it'll use floating point arithmetic. For example:
double offset = 100.0 / hmm;
try using
offset = 100./hmm;
The problem is you're using integer division.
You are performing an integer division between 100 and hmm. The result would always be an integer, and you are seeing it produce 0 because hmm is greater than 100 in your case.
Try this instead:
offset = 100f / hmm; // the trailing f makes 100 a float
The problem is the last line of code. If you write 100 / hmm the result will be seen as integer value as 100 is an integer. Try using
((double)100)/hmm;
Integer division always drops the decimal point. Therefore, something like 1 / 100 = .01 would just become 0.
hmm is an int. Try declaring it as a float or double, or cast it as such when you perform the calculation.
IE.
offset = 100 / ((double)hmm);

Categories

Resources