C# is there a problem with division? - c#

This is a piece of my code, it is called every second, after about 10 seconds the values start to become weird (see below):
double a;
double b;
for (int i = 0; i < currAC.Length; i++ )
{
a = currAC[i];
b = aveACValues[i];
divisor = (a/b);
Console.WriteLine("a = " + a.ToString("N2") + "\t" + "b = " + b.ToString("N2"));
Console.WriteLine("divisor = " + divisor);
Console.WriteLine("a+b = " + (a+b));
}
and the output:
a = -0.05 b = 0.00
divisor = 41
a+b = -0.0524010372273268
currAC and aveACValues are double[]
what on earth is going on???? The addition result is correct every time, but the division value is wrong, yet it is reading a and b correctly??
EDIT: '41' is the value of the first calculation, ie when a = currAC[0], but this should not remain???

if b == -0.001219512195122, then a/b==41, and a+b==-0.051219512195122 - so something around those areas (rounding etc) sounds feasible...
Also; note that for some arithmetic, it is possible it is using values that are still in registers. Registers may exhibit slightly different accuracy (and so give different results) than local variables.

double can result in inprecise results, due to the specification (see msdn). You might want to use decimal instead, it offers more precision.

What happens if the variables are declared as close to where they are used as is possible?
for (int i = 0; i < currAC.Length; i++ )
{
double a = currAC[i];
double b = aveACValues[i];
double divisor = (a/b);
Console.WriteLine("a = " + a.ToString("N2") + "\t" + "b = " + b.ToString("N2"));
Console.WriteLine("divisor = " + divisor.ToString());
Console.WriteLine("a+b = " + (a+b).ToString());
}
This would ensure that you have a fresh "divisor" each time and will not be affected by other scopes.

Related

C# for loop that gives sum of i/(i+1) through user specificed number

I need to display sum(i) = 1/2 + 2/3 + 3/4 + ... i/(i+1) where the final i is specified by the user. For some reason I am getting error "use of unassigned variable" for the second "total" in this line of code:
double total = (double) total + (i / (i + 1));
I tried to declare total outside the for loop but then it always comes out equal to 0.
Here is the full code:
public static void DisplaySums(int lastNum)
{
Console.WriteLine("i\tSum(i)");
for (int i=1; i<=(lastNum); i++)
{
double total = (double) total + (i / (i + 1));
Console.WriteLine(i + "\t" + total);
}
}
static void Main(string[] args)
{
Console.Write("Enter an integer: ");
int n = Convert.ToInt32(Console.ReadLine());
DisplaySums(n);
This is my first time ever asking a question on StackOverflow so I hope this makes sense. I can clarify if needed!
Thank you :)
First, you have to declare total outside of the loop. Else you are not summing up any intermediate results.
Second, you're getting zero because
(i / (i + 1))
performs integer division which is automatically truncated. To keep the decimal number, use a double literal:
(i / (i + 1.0))
In this line
double total = (double) total + (i / (i + 1));
You are essentially saying total is equal to itself plus something else. However the compiler doesn't know what total is as you just declared it. You need to assign the variable before you can use it.
Also (i / (i + 1)) is integer division. Which from the docs:
When you divide two integers, the result is always an integer
Anything divided by itself plus one will not be a whole number and the remainder will get thrown away and 0 will be returned. To fix this change (i / (i + 1)) to (i / (i + 1.0))
There are two issues here; the biggest obviously being your compile time error use of unassigned variable. This is because you are trying to assign the value of your newly instantiated variable as it is instantiated. A good idea is to instantiate to zero. You should also do this outside of your loop to retain the value with every iteration.
double total = 0;
Console.WriteLine("i\tSum(i)");
for (int i = 1; i <= lastNum; i++) {
total += (i / (i + 1));
Console.WriteLine(i + "\t" + total);
}
The next issue you are having is the result of zero every time. This is because the division is being performed on integers and integers are any whole number, thus a value such as 0.25 is rounded down to 0. If you revise your loop and your parameter in your method to use the double type instead, this issue will be resolved:
private static void DisplaySums(double lastNum) {
double total = 0;
Console.WriteLine("i\tSum(i)");
for (double d = 1; d <= lastNum; d++) {
total += (d / (d + 1));
Console.WriteLine(d + "\t" + total);
}
}

error CS1525 why does it happen?

I don't know why but when I'm trying to compile the next code I'm getting error CS1525 and every ) at the end of every while command is being marked as an error:
static void PrintArray(string[] arr)
{
int i, sum = 0, subb = 0, pow, x;
char opper;
Console.WriteLine("how many numbers does your calculation have?");
i = Convert.ToInt16(Console.ReadLine());
arr = new string[i];
for (i = 0; i < arr.Length; i++)
{
Console.WriteLine("enter num {0}" + i);
arr[i] = Console.ReadLine();
Console.WriteLine("arr[{0}] = {1}" + i, arr[i]);
}
Console.WriteLine("what do you want to do?");
opper = Convert.ToChar(Console.ReadLine());
while (opper = +)
{
for (i = 0; i < arr.Length; i++)
{
sum = sum + Convert.ToInt16(arr[i]);
}
Console.WriteLine("your sum is " + sum);
}
while (opper = -)
{
for (i = 0; i < arr.Length; i++)
{
subb = subb + Convert.ToInt16(arr[i]);
}
Console.WriteLine("your subb is" + subb);
}
while (opper = *)
{
pow = Convert.ToInt16(arr[0]);
for (i = 1; i < arr.Length; i++)
{
pow = pow * Convert.ToInt16(arr[i]);
}
Console.WriteLine("the resolt is " + pow);
}
while (opper = &)
{
x = Convert.ToInt16(arr[i]);
for (i = 0; i < arr.Length; i++)
{
x = x / Convert.ToInt16(arr[i]);
}
Console.WriteLine("your resolt is " + x);
}
Console.ReadKey();
}
I will be glad if someone can finally explain that to me...
Given the lines (for example)
opper = Convert.ToChar(Console.ReadLine());
while (opper = +)
It looks like you're trying to compare the character input to an operator. You'll want to change the assignment operator to a comparison operator, and compare the character to another character, like so:
opper = Convert.ToChar(Console.ReadLine());
while (opper == '+')
user1673882 is correct here about the cause of the compile error. However, there are several other significant bugs you should be aware of as well.
As for the original compile issue, you have two issues with the following line (and all similar lines);
while (opper = +)
First, = (single "equals" sign) is assignment, not comparison. You want to use == here instead.
Secondly, + is not a character in this case, it's an operation. (In fact, the compiler can't infer exactly which operator it might be).
Even if you get this to compile, though, it won't work because all of your loops are infinite loops. Consider this example:
char myChar = 'a';
// Infinite loop
while (myChar == 'a')
{
Console.WriteLine("Test");
}
How could this possibly get out of the loop, given that myChar will always be a?
A few other miscellaneous bugs follow:
subb = subb + Convert.ToInt16(arr[i]);
This could be shortened with
subb += Convert.ToInt16(arr[i]);
or possibly even
subb += (short)arr[i];
Also, I'm assuming this shouldn't be "+" since that's exactly the same operation you're doing if the operation is "+" (i.e. the outcome of "+" and "-" should be exactly the same).
x = x / Convert.ToInt16(arr[i]);
First, same cleanup as above:
x /= (short)arr[i];
Secondly, you never test for division by 0 here, so this might throw an exception.
Third, I'm not sure what type x is, but "short" is definitely not closed over division - i.e.:
short a = ...
short b...
// May not be another short
Console.WriteLine(a / b);
Actually, this applies to multiplication, subtraction, and addition to some extent too in this case since shorts have a finite size. Consider the following code:
short overflow = short.MaxValue;
// -32768
overflow++;
// +32767
overflow--;
// -32768 again
overflow++;
// -32767
overflow++;
checked
{
overflow = short.MaxValue;
// Now this results in an OverflowException
overflow++;
}
One more example:
short testArithmetic = 1;
// This gives us the result that 1 / 2 = 0.
testArithmetic /= 2;
// Set this back to 1 for the next operation
testArithmetic = 1;
// This is 0.0 too!
double testArithmeticFloat = testArithmetic / 2;
// This gives us the result we'd expect
testArithmeticFloat = 1.0 / 2.0;
// This'll compile just fine, but you get a DivideByZeroException when you try to execute it
testArithmetic /= 0;

Input string was not in a correct format. c# (New)

I'm having "Input string was not in a correct format." error from this code
rainTb.Text = " " + int.Parse(parsed[0]) * 100 / 1023;
There's no error in my code. Except for the error above. I've made a calculation to extract the analogue value (above calculation) from Arduino hardware via serial communication (cable). Arduino works fine though. Everything was fine though until this error shows up... Why? cries
p/s : I've gone through many solutions but still.. So here I am now. Sorry for my English
private void ProcessCOMRx(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(COMRx))
{
systemTb.Text = "Processing Data...";
systemTb.BackColor = System.Drawing.Color.Lime;
string [] parsed = COMRx.Split(',');
int curveNo;
if (parsed.Count() > zedAll.GraphPane.CurveList.Count())
curveNo = zedAll.GraphPane.CurveList.Count();
else
curveNo = parsed.Count();
for (int k = 0; k < curveNo; k++)
{
for (int j = zedAll.GraphPane.CurveList[k].NPts - 1; j > 0; j--)
{
zedAll.GraphPane.CurveList[k].Points[j].Y = zedAll.GraphPane.CurveList[k].Points[j - 1].Y;
}
double temp = 0;
try
{
temp = double.Parse(parsed[k]);
}
catch
{
systemTb.Text = "Parse Error";
systemTb.BackColor = System.Drawing.Color.Red;
}
rainTb.Text = "" + int.Parse(parsed[0]) * 100 / 1023;
phTb.Text = "" + (3.5 + int.Parse(parsed[1]) * 4.5 / 1023);
moistTb.Text = "" + int.Parse(parsed[2]) * 100 / 1023;
tempTb.Text = "" + int.Parse(parsed[3]) * 100 / 1023;
zedAll.GraphPane.CurveList[k].Points[0].X = 0;
zedAll.GraphPane.CurveList[k].Points[0].Y = temp;
}
}
else
{
this.BeginInvoke(new EventHandler(processPumpStates));
}
}
There are few possible cases why it happens. One is because (1) parsed[0] number is too big, another is because parsed[0] contains (2) non-number, (3) non-recognized thousand separators, or (4) decimal separator (which should not exist in int parsing) in the applied culture for your code.
In all cases, please check the value of parsed[0] with your Visual Studio debugger and make sure that it has purely-acceptable numerical format for int range. Something like:
1234
Also, you may consider of
using TryParse instead of Parse to ensure that the non-parsed number does not cause you exception problem.
use ToString() for printing your numerical calculation result,
check the result of TryParse and
beware of the integer division that you potentially do in the original int.Parse(parsed[0]) * 100 / 1023:
Something like this:
int val;
bool result = int.TryParse(parsed[0], out val);
if (!result)
return; //something has gone wrong
Textbox1.Text = " " + (val * 100d / 1023d).ToString(); //note the d
You are getting such error on the basics of the value contained in the parsed[0] if it is a convertible string your code works fine else it throws the exception that you got. ie, the content inside the parsed[0] is not convertible to an integer, in such situations you should Use int.TryParse instead for int.Parse, it is having internal error handling, which help you to determine whether the conversion is successful or not.
So the code will looks like:
int tempNumber=0;
if (int.TryParse(parsed[0], out tempNumber))
{
Textbox1.Text = " " + (tempNumber * 100 / 1023).ToString();
}
else
{
Textbox1.Text= "invalid zipCode";
}

Converting C# to idiomatic R

Originally, I was using a short C# program I wrote to average some numbers. But now I want to do more extensive analysis so I converted my C# code to R. However, I really don't think that I am doing it the proper way in R or taking advantage of the language. I wrote the R in the exact same way I did the C#.
I have a CSV with two columns. The first column identifies the row's type (one of three values: C, E, or P) and the second column has a number. I want to average the numbers grouped on the type (C, E, or P).
My question is, what is the idiomatic way of doing this in R?
C# code:
string path = "data.csv";
string[] lines = File.ReadAllLines(path);
int cntC = 0; int cntE = 0; int cntP = 0; //counts
double totC = 0; double totE = 0; double totP = 0; //totals
foreach (string line in lines)
{
String[] cells = line.Split(',');
if (cells[1] == "NA") continue; //skip missing data
if (cells[0] == "C")
{
totC += Convert.ToDouble(cells[1]);
cntC++;
}
else if (cells[0] == "E")
{
totE += Convert.ToDouble(cells[1]);
cntE++;
}
else if (cells[0] == "P")
{
totP += Convert.ToDouble(cells[1]);
cntP++;
}
}
Console.WriteLine("C found " + cntC + " times with a total of " + totC + " and an average of " + totC / cntC);
Console.WriteLine("E found " + cntE + " times with a total of " + totE + " and an average of " + totE / cntE);
Console.WriteLine("P found " + cntP + " times with a total of " + totP + " and an average of " + totP / cntP);
R code:
dat = read.csv("data.csv", header = TRUE)
cntC = 0; cntE = 0; cntP = 0 # counts
totC = 0; totE = 0; totP = 0 # totals
for(i in 1:nrow(dat))
{
if(is.na(dat[i,2])) # missing data
next
if(dat[i,1] == "C"){
totC = totC + dat[i,2]
cntC = cntC + 1
}
if(dat[i,1] == "E"){
totE = totE + dat[i,2]
cntE = cntE + 1
}
if(dat[i,1] == "P"){
totP = totP + dat[i,2]
cntP = cntP + 1
}
}
sprintf("C found %d times with a total of %f and an average of %f", cntC, totC, (totC / cntC))
sprintf("E found %d times with a total of %f and an average of %f", cntE, totE, (totE / cntE))
sprintf("P found %d times with a total of %f and an average of %f", cntP, totP, (totP / cntP))
I would use the data.table package since it has group by functionality built in.
library(data.table)
dat <- data.table(dat)
dat[, mean(COL_NAME_TO_TAKE_MEAN_OF), by=COL_NAME_TO_GROUP_BY]
# no quotes for the column names
If you would like to take the mean (or perform other function) on multiple columns, still by group, use:
dat[, lapply(.SD, mean), by=COL_NAME_TO_GROUP_BY]
Alternatively, if you want to use Base R, you could use something like
by(dat, dat[, 1], lapply, mean)
# to convert the results to a data.frame, use
do.call(rbind, by(dat, dat[, 1], lapply, mean) )
I would do something like this :
dat = dat[complete.cases(dat),] ## The R way to remove missing data
dat[,2] <- as.numeric(dat[,2]) ## convert to numeric as you do in c#
by(dat[,2],dat[,1],mean) ## compute the mean by group
Of course to aggregate your result in a data.frame you can use the the classic , But I don't think is necessary here since it a list of 3 variables:
do.call(rbind,result)
EDIT1
Another option here is to use the elegant ave :
ave(dat[,2],dat[,1])
But the result is different here. In the sense you will get a vector of the same length as your original data.
EDIT2 To include more results you can elaborate your anonymous function:
by(dat[,2],dat[,1],function(x) c(min(x),max(x),mean(x),sd(x)))
Or returns data.frame more suitable to rbind call and with columns names:
by(dat[,2],dat[,1],function(x)
data.frame(min=min(x),max=max(x),mean=mean(x),sd=sd(x)))
Or use the elegant built-in function ( you can define your's also) summary:
by(dat[,2],dat[,1],summary)
One way:
library(plyr)
ddply(dat, .(columnOneName), summarize, Average = mean(columnTwoName))

C# ++ unary operator increment issue

Question regarding the C# ++ (right placed) operator.
As the left placed ++ operator, for example, ++var, (say holding an int value of 1) will increment by 1 before any other computation takes place (example value of 1 will become 2 after expression is executed and result displayed).
Can anyone explain the difference between the left placed operator and the right placed operator? (var++) as it does not seem to increment even after the expression is executed as it is supposed to do. Here is some sample code:
int var1, var2 = 5, var3 = 6;
var1 = var2++ * --var3;
Console.WriteLine(" {0} ", var1);
Console.ReadKey();
This is just 5 x 5 due to the decrement of var3 but without the decrement it is 5 x 6 and var2++ appears to have no effect other than the value of 5 it carries. If anyone can shed light on this topic I would be grateful. Thanks.
***Issue solved. A lot of great answers and input guys, was hard trying to decide what answer to accept but you are all winners here! Thanks again for the help! =)
int var1, var2 = 5, var3 = 6;
var1 = var2++ * --var3;
Console.WriteLine(" {0} ", var1);
Console.WriteLine(" {0} ", var2);
Console.ReadKey();
Output:
25
6
So var2 is incremented as expected.
++x (prefix increment) increments the value before the expression is evaluated. Thus it first increments the value and then returns it.
x++ (postfix increment) increments the value after the expression is evaluated. Thus, it returns the unchanged value, and only after that, x is incremented.
After the line var1 = var2++ * --var3;, var2 is actually 6, because it was incremented after its value was evaluated.
So your code:
var1 = var2++ * --var3;
does something like this:
int oldVar2 = var2;
var2 = var2 + 1;
var3 = var3 - 1;
var1 = oldVar2 * var3;
In C# the only difference between left-placed operator and right-placed operator is the actual returned value after computation.
In case of left-hand operator, returned new, or incremented value.
In case of right-hand operator, returned value is the "old" one, even if the real value was incremented.
But important to know that in both cases the sequence of operations executed is exactly the same.
The var2 value is incremented after evaluation for the multiplication; the var3 value is decremented before evaluation for the multiplication; it can be roughly conceptualised as:
var tmp = var2; // 5
var2 = var2 + 1; // 5 + 1 = 6
var3 = var3 - 1; // 6 - 1 = 5;
var1 = tmp * var3; // 5 * 5 = 25;
So the 25 is correct. If you inspect var2 you will find that it has incremented as expected.
However! If a complex calculation involving ++foo and bar-- gets confusing, then simply don't do it inline; break the computation down into simpler pieces, and execute that. The compiler won't judge you.
Here is some sample class leveraging concept of PreFix and PostFix increment operators. The code is written with comments making the output more clearer.
public class Test
{
public Test()
{ }
public static void Main(string[] args)
{
int i = 0;
Console.WriteLine("\n" + "Displaying Initial i = " + i + "\n"); // Prints 0 i.e. Initial value of i
Console.WriteLine("\n" + "Displaying PostFix i++ = " + i++ + "\n"); // Prints 0. Then value of i becomes 1.
Console.WriteLine("\n" + "Displaying Post-incremented i = " + i + "\n"); // Prints 1 i.e. Value of i after Post-increment
Console.WriteLine("\n" + "Displaying PreFix ++i = " + ++i + "\n"); // Prints 2. Then value of i incremented to 2
Console.WriteLine("\n" + "Displaying Pre-incremented i = " + i + "\n"); // Prints 2 i.e. Value of i after Pre-increment
Console.WriteLine("\n" + "---------------------------------------------" + "\n");
int j = 0;
Console.WriteLine("\n" + "Displaying Initial j = " + j + "\n"); // Prints 0 i.e. Initial value of j
Console.WriteLine("\n" + "Displaying PreFix ++j = " + ++j + "\n"); // Prints 1. Then value of j incremented to 1.
Console.WriteLine("\n" + "Displaying Pre-incremented j = " + j + "\n"); // Prints 1 i.e. Value of j after Pre-increment
Console.WriteLine("\n" + "Displaying PostFix j++ = " + j++ + "\n"); // Prints 1. Then value of j incremented to 2.
Console.WriteLine("\n" + "Displaying Post-incremented j = " + j + "\n"); // Prints 2 i.e. Value of j after Post-increment
Console.ReadLine();
}
}

Categories