Why am I getting zero when I multiply doubles? - c#

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;

Related

Matching excels rounding in a C# application

I am currently in the process of turning a rather lofty Excel sheet that is used for calculating scientific values into a C# application. However, I am hitting some problems in regards to the rounding.
All of my values are stored as doubles, and when you perform a small number of operations on them they match the excel sheet within acceptable accuracy (5 or 6 decimal places). When they are put through rather large operations with division, multiplication, square roots. They start to drift off by quite a large margin. I switched the entire code base to decimals at another point to test if it resolved this issue, it lessened the gap but the issue still remained.
I am aware this is due to the nature of decimal numbers in software development, but it's imperative I match excels rounding as much as possible. Research on this topic points me towards the standards that excel uses to round and it seems C# by default uses a slightly different one. Despite learning of this I am still unsure of how to proceed on replicating excels rounding. I'm wondering if anyone has any advice or previous experience on this topic?
Any help would be greatly appreciated.
EDIT : I would just like to clarify that I am not rounding my numbers whatsoever. The rounding on both the sheet and my code is implicitly being applied. I have tested the same formulas inside of a totally different software package (A form builder called K2). The resulting numbers match my c# application so it seems excels implicit rounding differs in some way.
One of the offending formulas:
(8.04 * Math.Pow(10, -5)) *
(Math.Pow(preTestTestingDetails.PitotCp, 2)) * (DeltaH) *
(tempDGMAverage + 273.0) /
(StackTemp + 273) *
((preTestTestingDetails.BarometricPressure / 0.133322 +
((preTestTestingDetails.StackStaticPressure / 9.80665) / 13.6)) /
(preTestTestingDetails.BarometricPressure / 0.133322)) *
(preTestTestingDetails.EstimatedMolWeight /
((preTestTestingDetails.EstimatedMolWeight * (1 - (EstimatedMoisture / 100))) +
(18 * (EstimatedMoisture / 100)))) *
Math.Pow((1 - (EstimatedMoisture / 100)), 2) *
(Math.Pow(preTestTestingDetails.NozzleMean, 4));
In C# the result of
int x = 5;
var result = x / 2; // result is 2 and of type int
... because an integer division is performed. So if integers are involved (not a double with no decimals, but a value of type int or long), make sure to convert to double before dividing.
int x = 5;
double result = x / 2; // result is 2.0 because conversion to double is made after division
This works:
int x = 5;
var result = (double)x / 2; // result is 2.5 and of type double
int x = 5;
var result = x / 2.0; // result is 2.5 and of type double
int x = 5;
var result = 0.5 * x; // result is 2.5 and of type double
The only place in your formula where this could happen is EstimatedMoisture / 100, in case EstimatedMoisture is of type int. If this is the case, fix it with EstimatedMoisture / 100.0.
Instead of 8.04 * Math.Pow(10, -5), you can write 8.04e-5. This avoids rounding effects of Math.Pow!
I don't know how Math.Pow(a, b) works, but the general formula is a^b=exp(b*ln(a)). So instead of writing Math.Pow(something, 2), write something * something. This is both, faster and more accurate.
Using constants for magic numbers adds clarity. Using temps for common sub-expressions makes the formula more readable.
const double mmHg_to_kPa = 0.133322;
const double g0 = 9.80665;
var p = preTestTestingDetails;
double moisture = EstimatedMoisture / 100.0;
double dryness = 1.0 - moisture;
double pressure_mmHg = p.BarometricPressure / mmHg_to_kPa;
double nozzleMean2 = p.NozzleMean * p.NozzleMean;
double nozzleMean4 = nozzleMean2 * nozzleMean2;
double result = 8.04E-05 *
p.PitotCp * p.PitotCp * DeltaH * (tempDGMAverage + 273.0) / (StackTemp + 273.0) *
((pressure_mmHg + p.StackStaticPressure / g0 / 13.6) / pressure_mmHg) *
(p.EstimatedMolWeight / (p.EstimatedMolWeight * dryness + 18.0 * moisture)) *
dryness * dryness * nozzleMean4;
Why not use 273.15 instead of 273.0 if precision is a concern?

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

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

Why does this result in 0 and upsidedown not?

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;

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