C# ++ unary operator increment issue - c#

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();
}
}

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;

Read() only takes first input but no other input from other Console.Read()

I am following instructions in a C# Tutorial video that is great. I am building a file with the notes and code from the video.
I reviewed similar questions but they do not solve this problem.
Here is a copy of the CS file:
static void Main(string[] args)
{
// Single line comments
/* test multi-line comments
* asldkjasldkjaskd
* asldkjasldkja
* alsdkjalksdj
* */
Console.WriteLine("Hello world!");
Console.Write("What is your name? ");
string name = Console.ReadLine();
Console.WriteLine("Hello " + name);
bool canVote = true;
char grade = 'A';
// Integer with a max number of 2,147,483,647
int maxInt = int.MaxValue;
//Long with max value of 9,223,372,036,854,775,807
long maxLong = long.MaxValue;
// Decimal has a max value of 79,228,162,514,264,337,593,543,950,335
// If you need something bigger, look up BigInteger
decimal maxDecimal = decimal.MaxValue;
// A float is a 32 bit number with a max value of 3.402823E+38 with 7 decimal positions
float maxFloat = float.MaxValue;
// A double is a 32 bit number with a max value of 1.797693134E+308 with 15 decimal positions
double maxDouble = double.MaxValue;
Console.WriteLine("Max Int : " + maxInt);
Console.WriteLine("Max Long : " + maxLong);
Console.WriteLine("Max Decimal : " + maxDecimal);
Console.WriteLine("Max Float : " + maxFloat);
Console.WriteLine("Max Double : " + maxDouble);
var anotherName = "Tom";
// anotherName = 2; Cannot implicitly convert a gype 'int' to a 'string'
Console.WriteLine("anotherName is a {0}", anotherName.GetTypeCode());
// Math
Console.WriteLine("5 + 3 = " + (5 + 3));
Console.WriteLine("5 - 3 = " + (5 - 3));
Console.WriteLine("5 * 3 = " + (5 * 3));
Console.WriteLine("5 / 3 = " + (5 / 3));
Console.WriteLine("5.2 % 3 = " + (5.2 % 3));
int i = 0;
Console.WriteLine("i++ = " + (i++));
Console.WriteLine("++i = " + (++i));
Console.WriteLine("i-- = " + (i--));
Console.WriteLine("--i = " + (--i));
Console.WriteLine("i +- 3 = " + (i +- 3));
Console.WriteLine("i -= 2 = " + (i -= 2));
Console.WriteLine("i *= 2 = " + (i *= 2));
Console.WriteLine("i /= 2 = " + (i /= 2));
Console.WriteLine("i %= 2 = " + (i %= 2));
// casting
// if no magnitude is lost, casting will happen automatically. But otherwise, you set it up as follows
double pi = 3.14;
int intPi = (int)pi;
Console.WriteLine("intPi = " + intPi);
// Math functions
// Acos, Asin, Atan, Atan2, Cos, Cosh, Exp, Log, Sin, Sinh, Tan, Tanh
double number1 = 10.5;
double number2 = 15;
Console.WriteLine("number1 is " + number1);
Console.WriteLine("number2 is " + number2);
Console.WriteLine("Math.Abs(number1) " + (Math.Abs(number1)));
Console.WriteLine("Math.Ceiling(number2) " + (Math.Ceiling(number1)));
Console.WriteLine("Math.Floor(number1) " + (Math.Floor(number1)));
Console.WriteLine("Math.Max(number1,number2) " + (Math.Max(number1,number2)));
Console.WriteLine("Math.Min(number1,number2) " + (Math.Min(number1,number2)));
Console.WriteLine("Math.Pow(number1, 2) " + (Math.Pow(number1, 2)));
Console.WriteLine("Math.Round(number1) " + (Math.Round(number1)));
Console.WriteLine("Math.Sqrt(number1) " + (Math.Sqrt(number1)));
// random numbers
Random rand = new Random();
Console.WriteLine("Random number between 1 and 10 is " + rand.Next(1, 11));
// Relational operators : > < >= <= == !=
// Logical operators : && || ^ !
// note: ^ is the exclusive or
Console.WriteLine("What is your child's age? (enter 0 - 18)");
int age = Console.Read();
if ((age >= 5) && (age <= 7))
{
Console.WriteLine("Go to Elementary School");
} else if ((age > 7) && (age <= 13))
{
Console.WriteLine("Go to middle school");
} else if ((age < 5) || (age > 13))
{
Console.WriteLine("Your child does not meet our age requirements.");
} else
{
Console.WriteLine("Go to high school");
}
Console.WriteLine("What is your age? ");
int workingAge = Console.Read();
if ((workingAge < 14) || (workingAge > 67))
{
Console.WriteLine("You shouldn't work.");
}
}
The program ignores the input from the following:
Console.WriteLine("What is your age? ");
int workingAge = Console.Read();
The output is:
What is your age?
You shouldn't work.
So, the program is not stopping for my input, but rather seems to process its conditions based on the previous integer input value of 2 or 5.
Other articles talked about doing the following which I tried with no avail:
Console.WriteLine("What is your age? ");
int workingAge = Convert.ToInt32(Console.Read());
And
Console.WriteLine("What is your age? ");
int workingAge = int32.Parse(Console.Read());
The second one produced an error in Visual Studio The name 'int32' does not exist in the current context
I updated the script to use int.Parse(Console.ReadLine()), and it worked on Visual Studio 2007, but I ran this on Visual Studio 2015 Community Edition and it is doing the same exact thing as if the changes had no effect:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace HelloWorld
{
class Program
{
static void Main(string[] args)
{
// Single line comments
/* test multi-line comments
* asldkjasldkjaskd
* asldkjasldkja
* alsdkjalksdj
* */
Console.WriteLine("Hello world!");
Console.Write("What is your name? ");
string name = Console.ReadLine();
Console.WriteLine("Hello " + name);
bool canVote = true;
char grade = 'A';
// Integer with a max number of 2,147,483,647
int maxInt = int.MaxValue;
//Long with max value of 9,223,372,036,854,775,807
long maxLong = long.MaxValue;
// Decimal has a max value of 79,228,162,514,264,337,593,543,950,335
// If you need something bigger, look up BigInteger
decimal maxDecimal = decimal.MaxValue;
// A float is a 32 bit number with a max value of 3.402823E+38 with 7 decimal positions
float maxFloat = float.MaxValue;
// A double is a 32 bit number with a max value of 1.797693134E+308 with 15 decimal positions
double maxDouble = double.MaxValue;
Console.WriteLine("Max Int : " + maxInt);
Console.WriteLine("Max Long : " + maxLong);
Console.WriteLine("Max Decimal : " + maxDecimal);
Console.WriteLine("Max Float : " + maxFloat);
Console.WriteLine("Max Double : " + maxDouble);
var anotherName = "Tom";
// anotherName = 2; Cannot implicitly convert a gype 'int' to a 'string'
Console.WriteLine("anotherName is a {0}", anotherName.GetTypeCode());
// Math
Console.WriteLine("5 + 3 = " + (5 + 3));
Console.WriteLine("5 - 3 = " + (5 - 3));
Console.WriteLine("5 * 3 = " + (5 * 3));
Console.WriteLine("5 / 3 = " + (5 / 3));
Console.WriteLine("5.2 % 3 = " + (5.2 % 3));
int i = 0;
Console.WriteLine("i++ = " + (i++));
Console.WriteLine("++i = " + (++i));
Console.WriteLine("i-- = " + (i--));
Console.WriteLine("--i = " + (--i));
Console.WriteLine("i +- 3 = " + (i + -3));
Console.WriteLine("i -= 2 = " + (i -= 2));
Console.WriteLine("i *= 2 = " + (i *= 2));
Console.WriteLine("i /= 2 = " + (i /= 2));
Console.WriteLine("i %= 2 = " + (i %= 2));
// casting
// if no magnitude is lost, casting will happen automatically. But otherwise, you set it up as follows
double pi = 3.14;
int intPi = (int)pi;
Console.WriteLine("intPi = " + intPi);
// Math functions
// Acos, Asin, Atan, Atan2, Cos, Cosh, Exp, Log, Sin, Sinh, Tan, Tanh
double number1 = 10.5;
double number2 = 15;
Console.WriteLine("number1 is " + number1);
Console.WriteLine("number2 is " + number2);
Console.WriteLine("Math.Abs(number1) " + (Math.Abs(number1)));
Console.WriteLine("Math.Ceiling(number2) " + (Math.Ceiling(number1)));
Console.WriteLine("Math.Floor(number1) " + (Math.Floor(number1)));
Console.WriteLine("Math.Max(number1,number2) " + (Math.Max(number1, number2)));
Console.WriteLine("Math.Min(number1,number2) " + (Math.Min(number1, number2)));
Console.WriteLine("Math.Pow(number1, 2) " + (Math.Pow(number1, 2)));
Console.WriteLine("Math.Round(number1) " + (Math.Round(number1)));
Console.WriteLine("Math.Sqrt(number1) " + (Math.Sqrt(number1)));
// random numbers
Random rand = new Random();
Console.WriteLine("Random number between 1 and 10 is " + rand.Next(1, 11));
// Relational operators : > < >= <= == !=
// Logical operators : && || ^ !
// note: ^ is the exclusive or
Console.WriteLine("What is your child's age? (enter 0 - 18)");
int age = int.Parse(Console.ReadLine());
if ((age >= 5) && (age <= 7))
{
Console.WriteLine("Go to Elementary School");
}
else if ((age > 7) && (age <= 13))
{
Console.WriteLine("Go to middle school");
}
else if ((age < 4) || (age > 18))
{
Console.WriteLine("Your child does not meet our age requirements.");
}
else
{
Console.WriteLine("Go to high school");
}
Console.WriteLine("What is your age? ");
int workingAge = int.Parse(Console.ReadLine());
if ((workingAge < 14) || (workingAge > 67))
{
Console.WriteLine("You shouldn't work.");
}
else
{
Console.WriteLine("Work harder and smarter to get ahead.");
}
}
}
}
Please help.
.Read() reads only a single character. You probably want .ReadLine() instead, which reads all the characters up to Enter, and returns a string.
int workingAge = int.Parse(Console.ReadLine());
Expanding off of #recursive you can use int32.TryParse() to check if a valid number was supplied.
bool valid = false;
int workingAge;
while (!valid)
{
valid = int32.TryParse(Console.ReadLine(), out workingAge);
if (!valid)
Console.WriteLine("Supplied number was invalid");
}
// Rest of code
Edit: I think this can be simplified even further by doing the following:
int workingAge;
while (!int32.TryParse(Console.ReadLine(), out workingAge))
{
Console.WriteLine("Supplied number was invalid");
}
// Rest of code
I will add to recursive's solution and explain what is happening.
since you are using Console.Read() in two different areas -
and since Console.Read() reads one key input (i.e '1') -
you are probably entering two different digits in the first occurance which causes the first .Read() to only read the first digit, and "passes" the second digit to the second .Read()
as was said before me, changing the .Read() to .ReadLine() will solve your issue.

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# is there a problem with division?

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.

Categories