Average of Strings With 2 Decimal Points - c#

Using C#, I have 5 strings that are reading data from a temperature sensor on an Arduino board:
string currentTemp1 = serialPort1.ReadLine();
Thread.Sleep(1000);
string currentTemp2 = serialPort1.ReadLine();
Thread.Sleep(1000);..... and so on.
This is returning the values into the strings such as: 19.45, 19.45, 19.50, 19.45, 19.50.
I've tried a bit of research into trying to get the average, but am having problems working out how to convert the strings with the 2 decimal places into an Integer, and then getting the average.
Can someone please point me in the right direction.

The problem is that you don't want to parse the strings into integers. You should use float/double/decimal instead:
var temp1 = float.Parse(currentTemp1);
var temp2 = float.Parse(currentTemp2);
var average = (temp1 + temp2) / 2;
Or, you could use a loop if there's a variable number of integers:
var temps = currentTemp1.Split(", ");
float total;
foreach (var t in temps)
{
total += float.Parse(t);
}
var average = total / temps.Length;

Related

Put space between digits in C#

I'm need generate a random number an insert a space or comma between digits. This value will be speaked using AWS Polly. Without space, to 6565, she sepeak "six thousand five hundred and sixty five".
Part of the code, generating the random number, I already got it, but I don't know how to insert the space between the digits.
Anyone can help me? See bellow:
var withoutSpaces = new Random().Next(10000,100000);
var withSpaces = ????????
return withSpaces;
Wait your answer!
var withoutSpaces = new Random().Next(10000, 100000);
string withSpaces = "";
for (int i = 0; i < withoutSpaces.ToString().Length; i++)
{
string test = withoutSpaces.ToString().ElementAt(i) + " ";
withSpaces += test;
}
string WithSpacesFinal = withSpaces.Trim();
This should do it for you

Efficiently convert large BigInteger to string, ToString() takes too long

I was working on a factorial function, and factorial with big integers can get REALLY long.
For example, 200000! = 973350 digits long and if i just use ToString(), things take a very long time.
200000! takes longer to convert to string then actually compute it!
I've tried to set the factorial function to a Process, and then use ProcessorAffinity to pin the Thread to a specific core so that that core ONLY converts to string, but that just took exactly the same time.
Also, the reason I want to convert it to string is because I want to write the output (FactFile) to a text file.
String Conversion code:
using (Process proc = Process.GetCurrentProcess())
{
proc.ProcessorAffinity = (IntPtr)0x0003;
FactFile = Res.ToString(); //FactFile is Going to be the final string, Res is the Factorial.
}
here's my code for Factorial:
for (BigInteger i = 1; i < k; i++)
{
Res *= i; // Res is the number to Calculate the factorial of
}
200000! takes 15 seconds to compute, and then another 18 seconds to convert it to string (this can differ from cpu to cpu, I have an i7).
Reminder: What's the most efficient way to convert to string?
output:
Total Computation Time: 00:00:16.2007276
String Conversion Time: 00:00:19.4049292
Here is a 40% faster stringifier. It divides the big integer repeatedly with the number 10^10000, stringifies the remainder, and finally joins all the strings together. It can handle negative numbers also.
public static string ToDecimalString(this BigInteger value)
{
if (value == 0) return "0";
var digits = 10000;
var divider = BigInteger.Pow(10, digits);
var parts = new Stack<string>();
while (true)
{
BigInteger remainder;
value = BigInteger.DivRem(value, divider, out remainder);
if (value != 0)
{
parts.Push(BigInteger.Abs(remainder).ToString().PadLeft(digits, '0'));
}
else
{
parts.Push(remainder.ToString());
break;
}
}
return String.Join("", parts);
}
It can become slightly faster by offloading the stringifying of the remainders to a background thread. Unfortunately the slowest part of the algorithm (the call to BigInteger.DivRem) is not parallelizable.
public static string ToDecimalStringParallel(this BigInteger value)
{
if (value == 0) return "0";
var digits = 10000;
var divider = BigInteger.Pow(10, digits);
var remainders = new BlockingCollection<BigInteger>();
var parts = new ConcurrentStack<string>();
var task = Task.Run(() =>
{
foreach (var remainder in remainders.GetConsumingEnumerable())
{
parts.Push(BigInteger.Abs(remainder).ToString().PadLeft(digits, '0'));
}
});
while (true)
{
BigInteger remainder;
value = BigInteger.DivRem(value, divider, out remainder);
if (value != 0)
{
remainders.Add(remainder);
}
else
{
remainders.CompleteAdding();
task.Wait();
parts.Push(remainder.ToString());
break;
}
}
return String.Join("", parts);
}
For n! above n = 24, the result will have more digits than the value of input n.
That explosion of digits causes ToString to have to do more work than the factorial (n-1 multiplies vs more than n divides).
However because BigInteger operations take longer based on the magnitude of the numbers they work on, you can divide by a factor first, e.g. for your 200000! example:
var asString = Res.ToString()
Versus:
BigInteger[] bits = new BigInteger[2];
bits[0] = BigInteger.DivRem(Res, BigInteger.Pow(new BigInteger(10), 486675), out var remainder);
bits[1] = remainder;
var strs = new string[2];
System.Threading.Tasks.Parallel.For(0, 2, (i) =>
{
strs[i] = bits[i].ToString();
});
var asString = strs[0] + strs[1];
I found this to be 5 seconds faster but:
I had to choose a factor of 10^486675 to divide the digits equally - not sure how you'd do that in general
The initial DivRem takes 8 seconds
See also some existing attempts to speed up both factorial calculation and bigint to base 10 by breaking up the work.
The conclusion of the second one seemed to be.. don't convert large BigIntegers to base 10!

Multiplying Different Data Types in an Array in C#

I am receiving an error "Operator '*' cannot be applied to operands of type 'int' and 'decimal[]'", as I am attempting to multiply two values with different data types (one being a value located in an array). My question is how am I able to multiple numberOfMinutes * perMinuteRate in my code below? My variable is called total, which I declared a double data type (although may be incorrect).
I tried changing data types and played with formatting (like ToString), but I am not sure what to do. I also tried to google the answer with no success.
I am by no means a professional programmer; I'm not in school. I'm a data analyst who is learning to program.
Here is my code:
static void Main(string[] args)
{
int[] areaCodes = { 262, 414, 608, 715, 815, 920 };
decimal[] perMinuteRate = { .07m, .1m, .05m, .16m, .24m, .14m };
int numberOfMinutes;
int userAreaCode;
string inputString = "1";
while (inputString != "0")
{
int x;
Console.WriteLine("Enter the area code for your call (or 1 to end):");
inputString = Console.ReadLine();
userAreaCode = Convert.ToInt32(inputString);
Console.WriteLine("How many minutes will your call last?");
inputString = Console.ReadLine();
numberOfMinutes = Convert.ToInt32(inputString);
for (x = 0; x < areaCodes.Length; x++)
{
if (userAreaCode == areaCodes[x])
{
***double total = numberOfMinutes * perMinuteRate;***
Console.WriteLine("You call to {0} will cost {1} per minute for a total of {2}.", areaCodes[x], perMinuteRate[x].ToString("C"), total.ToString("C"));
x = areaCodes.Length;
}
}
if (x != areaCodes.Length)
{
Console.WriteLine("I'm sorry; we don't cover that area.");
inputString = "1";
}
else
{
Console.WriteLine("Thanks for being our customer.");
inputString = "0";
}
Console.ReadLine();
}
}
Thank you in advance.
Change:
double total = numberOfMinutes * perMinuteRate;
to
double total = (double)(numberOfMinutes * perMinuteRate[x]);
The same way you index into perMinuteRate in the line directly below.
The expression [int] * [decimal] will result in a decimal, and the cast (double) will convert it to a double
To avoid loss of precision, change it to:
decimal total = numberOfMinutes * perMinuteRate[x];

Reading .txt file into an array

I need to be able to read a text file into an array instead of inputting all the values myself.
The text file reads as:
8.7
9.3
7.9
6.4
9.6
8.0
8.8
9.1
7.7
9.9
5.8
6.9
The main purpose of the program is to read scores from a data file, store them in an array, and calculate the highest, lowest, total and average of the 12 scores.
The text file is stored in the Debug folder of the project.
This is what I've done so far:
Console.WriteLine("Numbers in the list: " + scores.Length);
//highest number
double high = scores[0];
for (int index = 1; index < scores.Length; index++)
{
if (scores[index] > high)
{
high = scores[index];
}
}
Console.WriteLine("Highest number = " + high);
//lowest number
double low = scores[0];
for (int index = 1; index < scores.Length; index++)
{
if (scores[index] < low)
{
low = scores[index];
}
}
Console.WriteLine("lowest number = " + low);
//average of the scores
double total = 0;
double average = 0;
for (int index = 0; index < scores.Length; index++)
{
total = total + scores[index];
}
average = (double)total / scores.Length;
Console.WriteLine("Total = " + total);
Console.WriteLine("Average = " + average.ToString("N2"));
Console.ReadKey();
}
}
}
You have no code in place for reading a file, or writing a file so that will be your problem. I suggest you start with looking at: StreamReader Class (MSDN).
Then you will probably want to look at the following: String.Split Method (MSDN)
To make the program a bit more dynamic you possible want to consider looking at this:
Application.ExecutablePath Property (MSDN)
Enviroment.GetFolderPath Method (MSDN) (This allows you to store data in better locations)
^^^^Original Response above^^^^^
Another option you could consider is described in a lot of detail here:
Working with Files - Code Project Article
You can use File.ReadLines method to read the lines lazily (means doesn't load all the lines to memory at once) from your file and Select method to take each line and parse it to double:
var values = File.ReadLines("path")
.Select(line => double.Parse(line))
.ToArray();
Then you can use Max,Min,Average methods from LINQ to get highest,lowest number and the average.
All of this can be writen easier :
using System;
using System.IO;
using System.Linq;
String path = #"MyFolder\myfile.txt"; // path for your file
// read the file
String[] lines = File.ReadAllLines(path);
// convert data in Doubles
Double[] data = Array.ConvertAll(lines, Double.Parse);
// use Linq to get what you want (min, max, total, average, ...)
Double low = data.Min();
Double high = data.Max();
Double total = data.Sum();
Double average = data.Average();
var scores = File.ReadAllLines("scores.txt").Select(x => Double.Parse(x)).ToArray();
var numbers = File.ReadAllLines(#"C:\numbers.txt")
.Select(n => double.Parse(n));
var max = numbers.Max();
var min = numbers.Min();
var sum = numbers.Sum();
var avg = numbers.Average();

Converting between negative Hexadecimal and negative Decimal gives wrong results

I am attempting to manually convert numbers between decimal and hexadecimal. I have it working for positive numbers and converting a negative decimal to 'negative' hexadecimal but I can't convert it from 'negative' hexadecimal to negative decimal.
Here is the code I am attempting to work with:
private string HexToDecimal(char[] toConvert)
{
if (negativeValue)
{
negativeValue = false;
long var = Convert.ToInt64(HexToDecimal(ResultLabel.Text.ToCharArray()));
long valueToHex = var - (long)Math.Pow(16, 15);
return ResultLabel.Text = valueToHex.ToString();
}
else
{
double total = 0;
//Convert hex to decimal
HexOrDecimalLabel.Text = "Decimal";
//TODO: create int array from indivial int
char[] charArray = toConvert;
long[] numberArray = HexSwitchFunction(charArray);
//TODO: reverse array
Array.Reverse(numberArray);
//loop array, times value by 16^i++, adding to total. This is the method used to convert hex to decimal
double power = 0;
foreach (int i in numberArray)
{
total += (i * (Math.Pow(16, power)));
power++;
}
//set the result label to total
isHex = false;
AllowHexButtons();
return ResultLabel.Text = total.ToString();
}
}
For instance, I can turn - 10 into FFFFFFFFFFFFFFF6, but when i attempt to turn that into decimal, I get 1.15292150460685E+18, which I can't do any equations with.
Does anyone know of a way around this?
This is because double uses a different representation for negative numbers. Changing the type of total and power from double to long will fix the problem.

Categories

Resources