How can user input function in C# - c#

I have made bisection method program in C# Console Application. Bisection method works, but for function which is already written in the code. I want to edit program that user can input function which they want to use for bisection method. For example Console.ReadLine() for input "x^2 + x - 2" and then I want it automatically written after return in the code below.
static double Function(double x)
{
return x*x - 2;
} //this is Function which I used in code.
Here is the whole code. (as i mentioned it works for function which is written in static double Function(double x) part
using System;
namespace MPI
{
class MainClass
{
public static void Main(string[] args)
{
// in [a,b]
double inPoc = 0; //a
double inKraj = 0; //b
double sredina = 0;
double tacnost = 0;
Start:
int i = 0; //brojac
Console.Write("Unesite početak intervala: ");
inPoc = Convert.ToDouble(Console.ReadLine());
Console.Write("Unesite kraj intervala: ");
inKraj = Convert.ToDouble(Console.ReadLine());
Console.Write("Unesite tacnost: ");
tacnost = Convert.ToDouble(Console.ReadLine());
sredina = (inPoc + inKraj) / 2;
if (Function(inPoc) * Function(inKraj) < 0)
{
while ((Math.Abs(inPoc - inKraj)) > tacnost)
{
sredina = (inPoc + inKraj) / 2;
Console.WriteLine("trenutno X: " + sredina);
Console.WriteLine("Funkcija za trenutno x ima vrednost: " + Function(sredina));
Console.WriteLine("");
i++;
if (Function(sredina) < 0)
{
inPoc = sredina;
}
else
{
inKraj = sredina;
}
}
Console.WriteLine("X: " + sredina);
Console.WriteLine("Broj izvrsenih koraka je " + i);
}
else
{
Console.WriteLine("Krajevi intervala funkcije su istog znaka");
Console.WriteLine();
}
goto Start; //sluzi da vrati program na pocetak kako bi ga opet koristili
}
static double Function(double x)
{
return x*x - 2; //primer funkcije
}
}
}

Looks like this question is asking about the same.
There are two solutions to do this:
Solution 1 - just use Flee.
Copy-paste from documentation:
ExpressionContext context = new ExpressionContext();
VariableCollection variables = context.Variables;
variables.Add("a", 100);
variables.Add("b", 1);
variables.Add("c", 24);
IGenericExpression<bool> e = context.CompileGeneric<bool>("(a = 100 OR b > 0) AND c <> 2");
bool result = e.Evaluate();
So you can do the same, just change input/output types and put your input line into the CompileGeneric
Solution 2 - parse input string manually.
So question can be divided to the two parts:
How to parse input string into the expression tree.
How to execute this tree.
For the first item - please check reverse polish notation. It allows to construct computation stack.
Next you will able to compute your expression tree. Each operand (after trimming) will have variable or integer constant. So just replace variable to the actual value and just parse string to the integer.

Related

Floyds Triangle as a method

How can I put my code into a method to work because now it has an error and I can't figure out how to solve it. In our exam we have to put every exercise into a method but now it says 'Cannot implicity convert type 'int' to 'string' when i try to return it (the 'n' is underlined).
public string FloydsTriangle(int n)
{
Console.Write("Enter a number: ");
int num = Convert.ToInt32(Console.ReadLine());
int count = 1;
for (int i = num; i > 0; i--)
{
for (int j = num; j >= i; j--)
{
Console.Write(count + " ");
count++;
}
Console.WriteLine();
}
Console.ReadLine();
return n;
}
Currently your code doesn't make a lot of sense, since you have a method which takes in an int, but does nothing with it, and returns a string, which is just the same int the user passed in only converted to a string (assuming you add .ToString() to the return value as mentioned in the other answer).
One idea to make this work would be to use the int argument as the basis for the triangle, and then to return a string representation of the triangle (instead of reading or writing anything to the console inside this method).
Note, I did not correct any of your existing code - I only changed how the method uses the input parameter and how it outputs the result:
public static string GetFloydsTriangle(int n)
{
int count = 1;
// Instead of writing strings to the console, we'll
// store them in this string and return it at the end
string triangle = string.Empty;
for (int i = n; i > 0; i--)
{
for (int j = n; j >= i; j--)
{
triangle = triangle + count + " ";
count++;
}
triangle = triangle + Environment.NewLine;
}
return triangle;
}
Then, to use the method, we will ask the user for a number in the Main method, then pass that to our method. Additionally, we'll capture the return value from the triangle method (which is our triangle string), and write that string to the console in the Main method.
This is a pretty standard way to write a helper method - it just does some calculations based on input data and returns a result (it doesn't interact with the user or UI).
Again, I am not correcting your code, only refactoring it to use the new method:
static void Main(string[] args)
{
Console.Write("Enter a number: ");
int num = Convert.ToInt32(Console.ReadLine());
string triangle = GetFloydsTriangle(num);
Console.WriteLine(triangle);
Console.Write("\nDone! Press any key to exit...");
Console.ReadKey();
}
Your method specifies that you'll be passing back a string. You'll want to do something like:
return n.toString();
Otherwise you'll need to change your method to:
public int FloydsTriangle(int n)

C# Parse String To Double Without Scientific Notation [duplicate]

How to convert a double into a floating-point string representation without scientific notation in the .NET Framework?
"Small" samples (effective numbers may be of any size, such as 1.5E200 or 1e-200) :
3248971234698200000000000000000000000000000000
0.00000000000000000000000000000000000023897356978234562
None of the standard number formats are like this, and a custom format also doesn't seem to allow having an open number of digits after the decimal separator.
This is not a duplicate of How to convert double to string without the power to 10 representation (E-05) because the answers given there do not solve the issue at hand. The accepted solution in this question was to use a fixed point (such as 20 digits), which is not what I want. A fixed point formatting and trimming the redundant 0 doesn't solve the issue either because the max width for fixed width is 99 characters.
Note: the solution has to deal correctly with custom number formats (e.g. other decimal separator, depending on culture information).
Edit: The question is really only about displaing aforementioned numbers. I'm aware of how floating point numbers work and what numbers can be used and computed with them.
For a general-purpose¹ solution you need to preserve 339 places:
doubleValue.ToString("0." + new string('#', 339))
The maximum number of non-zero decimal digits is 16. 15 are on the right side of the decimal point. The exponent can move those 15 digits a maximum of 324 places to the right. (See the range and precision.)
It works for double.Epsilon, double.MinValue, double.MaxValue, and anything in between.
The performance will be much greater than the regex/string manipulation solutions since all formatting and string work is done in one pass by unmanaged CLR code. Also, the code is much simpler to prove correct.
For ease of use and even better performance, make it a constant:
public static class FormatStrings
{
public const string DoubleFixedPoint = "0.###################################################################################################################################################################################################################################################################################################################################################";
}
¹ Update: I mistakenly said that this was also a lossless solution. In fact it is not, since ToString does its normal display rounding for all formats except r. Live example. Thanks, #Loathing! Please see Lothing’s answer if you need the ability to roundtrip in fixed point notation (i.e, if you’re using .ToString("r") today).
I had a similar problem and this worked for me:
doubleValue.ToString("F99").TrimEnd('0')
F99 may be overkill, but you get the idea.
This is a string parsing solution where the source number (double) is converted into a string and parsed into its constituent components. It is then reassembled by rules into the full-length numeric representation. It also accounts for locale as requested.
Update: The tests of the conversions only include single-digit whole numbers, which is the norm, but the algorithm also works for something like: 239483.340901e-20
using System;
using System.Text;
using System.Globalization;
using System.Threading;
public class MyClass
{
public static void Main()
{
Console.WriteLine(ToLongString(1.23e-2));
Console.WriteLine(ToLongString(1.234e-5)); // 0.00010234
Console.WriteLine(ToLongString(1.2345E-10)); // 0.00000001002345
Console.WriteLine(ToLongString(1.23456E-20)); // 0.00000000000000000100023456
Console.WriteLine(ToLongString(5E-20));
Console.WriteLine("");
Console.WriteLine(ToLongString(1.23E+2)); // 123
Console.WriteLine(ToLongString(1.234e5)); // 1023400
Console.WriteLine(ToLongString(1.2345E10)); // 1002345000000
Console.WriteLine(ToLongString(-7.576E-05)); // -0.00007576
Console.WriteLine(ToLongString(1.23456e20));
Console.WriteLine(ToLongString(5e+20));
Console.WriteLine("");
Console.WriteLine(ToLongString(9.1093822E-31)); // mass of an electron
Console.WriteLine(ToLongString(5.9736e24)); // mass of the earth
Console.ReadLine();
}
private static string ToLongString(double input)
{
string strOrig = input.ToString();
string str = strOrig.ToUpper();
// if string representation was collapsed from scientific notation, just return it:
if (!str.Contains("E")) return strOrig;
bool negativeNumber = false;
if (str[0] == '-')
{
str = str.Remove(0, 1);
negativeNumber = true;
}
string sep = Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator;
char decSeparator = sep.ToCharArray()[0];
string[] exponentParts = str.Split('E');
string[] decimalParts = exponentParts[0].Split(decSeparator);
// fix missing decimal point:
if (decimalParts.Length==1) decimalParts = new string[]{exponentParts[0],"0"};
int exponentValue = int.Parse(exponentParts[1]);
string newNumber = decimalParts[0] + decimalParts[1];
string result;
if (exponentValue > 0)
{
result =
newNumber +
GetZeros(exponentValue - decimalParts[1].Length);
}
else // negative exponent
{
result =
"0" +
decSeparator +
GetZeros(exponentValue + decimalParts[0].Length) +
newNumber;
result = result.TrimEnd('0');
}
if (negativeNumber)
result = "-" + result;
return result;
}
private static string GetZeros(int zeroCount)
{
if (zeroCount < 0)
zeroCount = Math.Abs(zeroCount);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < zeroCount; i++) sb.Append("0");
return sb.ToString();
}
}
You could cast the double to decimal and then do ToString().
(0.000000005).ToString() // 5E-09
((decimal)(0.000000005)).ToString() // 0,000000005
I haven't done performance testing which is faster, casting from 64-bit double to 128-bit decimal or a format string of over 300 chars. Oh, and there might possibly be overflow errors during conversion, but if your values fit a decimal this should work fine.
Update: The casting seems to be a lot faster. Using a prepared format string as given in the other answer, formatting a million times takes 2.3 seconds and casting only 0.19 seconds. Repeatable. That's 10x faster. Now it's only about the value range.
This is what I've got so far, seems to work, but maybe someone has a better solution:
private static readonly Regex rxScientific = new Regex(#"^(?<sign>-?)(?<head>\d+)(\.(?<tail>\d*?)0*)?E(?<exponent>[+\-]\d+)$", RegexOptions.IgnoreCase|RegexOptions.ExplicitCapture|RegexOptions.CultureInvariant);
public static string ToFloatingPointString(double value) {
return ToFloatingPointString(value, NumberFormatInfo.CurrentInfo);
}
public static string ToFloatingPointString(double value, NumberFormatInfo formatInfo) {
string result = value.ToString("r", NumberFormatInfo.InvariantInfo);
Match match = rxScientific.Match(result);
if (match.Success) {
Debug.WriteLine("Found scientific format: {0} => [{1}] [{2}] [{3}] [{4}]", result, match.Groups["sign"], match.Groups["head"], match.Groups["tail"], match.Groups["exponent"]);
int exponent = int.Parse(match.Groups["exponent"].Value, NumberStyles.Integer, NumberFormatInfo.InvariantInfo);
StringBuilder builder = new StringBuilder(result.Length+Math.Abs(exponent));
builder.Append(match.Groups["sign"].Value);
if (exponent >= 0) {
builder.Append(match.Groups["head"].Value);
string tail = match.Groups["tail"].Value;
if (exponent < tail.Length) {
builder.Append(tail, 0, exponent);
builder.Append(formatInfo.NumberDecimalSeparator);
builder.Append(tail, exponent, tail.Length-exponent);
} else {
builder.Append(tail);
builder.Append('0', exponent-tail.Length);
}
} else {
builder.Append('0');
builder.Append(formatInfo.NumberDecimalSeparator);
builder.Append('0', (-exponent)-1);
builder.Append(match.Groups["head"].Value);
builder.Append(match.Groups["tail"].Value);
}
result = builder.ToString();
}
return result;
}
// test code
double x = 1.0;
for (int i = 0; i < 200; i++) {
x /= 10;
}
Console.WriteLine(x);
Console.WriteLine(ToFloatingPointString(x));
The problem using #.###...### or F99 is that it doesn't preserve precision at the ending decimal places, e.g:
String t1 = (0.0001/7).ToString("0." + new string('#', 339)); // 0.0000142857142857143
String t2 = (0.0001/7).ToString("r"); // 1.4285714285714287E-05
The problem with DecimalConverter.cs is that it is slow. This code is the same idea as Sasik's answer, but twice as fast. Unit test method at bottom.
public static class RoundTrip {
private static String[] zeros = new String[1000];
static RoundTrip() {
for (int i = 0; i < zeros.Length; i++) {
zeros[i] = new String('0', i);
}
}
private static String ToRoundTrip(double value) {
String str = value.ToString("r");
int x = str.IndexOf('E');
if (x < 0) return str;
int x1 = x + 1;
String exp = str.Substring(x1, str.Length - x1);
int e = int.Parse(exp);
String s = null;
int numDecimals = 0;
if (value < 0) {
int len = x - 3;
if (e >= 0) {
if (len > 0) {
s = str.Substring(0, 2) + str.Substring(3, len);
numDecimals = len;
}
else
s = str.Substring(0, 2);
}
else {
// remove the leading minus sign
if (len > 0) {
s = str.Substring(1, 1) + str.Substring(3, len);
numDecimals = len;
}
else
s = str.Substring(1, 1);
}
}
else {
int len = x - 2;
if (len > 0) {
s = str[0] + str.Substring(2, len);
numDecimals = len;
}
else
s = str[0].ToString();
}
if (e >= 0) {
e = e - numDecimals;
String z = (e < zeros.Length ? zeros[e] : new String('0', e));
s = s + z;
}
else {
e = (-e - 1);
String z = (e < zeros.Length ? zeros[e] : new String('0', e));
if (value < 0)
s = "-0." + z + s;
else
s = "0." + z + s;
}
return s;
}
private static void RoundTripUnitTest() {
StringBuilder sb33 = new StringBuilder();
double[] values = new [] { 123450000000000000.0, 1.0 / 7, 10000000000.0/7, 100000000000000000.0/7, 0.001/7, 0.0001/7, 100000000000000000.0, 0.00000000001,
1.23e-2, 1.234e-5, 1.2345E-10, 1.23456E-20, 5E-20, 1.23E+2, 1.234e5, 1.2345E10, -7.576E-05, 1.23456e20, 5e+20, 9.1093822E-31, 5.9736e24, double.Epsilon };
foreach (int sign in new [] { 1, -1 }) {
foreach (double val in values) {
double val2 = sign * val;
String s1 = val2.ToString("r");
String s2 = ToRoundTrip(val2);
double val2_ = double.Parse(s2);
double diff = Math.Abs(val2 - val2_);
if (diff != 0) {
throw new Exception("Value {0} did not pass ToRoundTrip.".Format2(val.ToString("r")));
}
sb33.AppendLine(s1);
sb33.AppendLine(s2);
sb33.AppendLine();
}
}
}
}
The obligatory Logarithm-based solution. Note that this solution, because it involves doing math, may reduce the accuracy of your number a little bit. Not heavily tested.
private static string DoubleToLongString(double x)
{
int shift = (int)Math.Log10(x);
if (Math.Abs(shift) <= 2)
{
return x.ToString();
}
if (shift < 0)
{
double y = x * Math.Pow(10, -shift);
return "0.".PadRight(-shift + 2, '0') + y.ToString().Substring(2);
}
else
{
double y = x * Math.Pow(10, 2 - shift);
return y + "".PadRight(shift - 2, '0');
}
}
Edit: If the decimal point crosses non-zero part of the number, this algorithm will fail miserably. I tried for simple and went too far.
In the old days when we had to write our own formatters, we'd isolate the mantissa and exponent and format them separately.
In this article by Jon Skeet (https://csharpindepth.com/articles/FloatingPoint) he provides a link to his DoubleConverter.cs routine that should do exactly what you want. Skeet also refers to this at extracting mantissa and exponent from double in c#.
I have just improvised on the code above to make it work for negative exponential values.
using System;
using System.Text.RegularExpressions;
using System.IO;
using System.Text;
using System.Threading;
namespace ConvertNumbersInScientificNotationToPlainNumbers
{
class Program
{
private static string ToLongString(double input)
{
string str = input.ToString(System.Globalization.CultureInfo.InvariantCulture);
// if string representation was collapsed from scientific notation, just return it:
if (!str.Contains("E")) return str;
var positive = true;
if (input < 0)
{
positive = false;
}
string sep = Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator;
char decSeparator = sep.ToCharArray()[0];
string[] exponentParts = str.Split('E');
string[] decimalParts = exponentParts[0].Split(decSeparator);
// fix missing decimal point:
if (decimalParts.Length == 1) decimalParts = new string[] { exponentParts[0], "0" };
int exponentValue = int.Parse(exponentParts[1]);
string newNumber = decimalParts[0].Replace("-", "").
Replace("+", "") + decimalParts[1];
string result;
if (exponentValue > 0)
{
if (positive)
result =
newNumber +
GetZeros(exponentValue - decimalParts[1].Length);
else
result = "-" +
newNumber +
GetZeros(exponentValue - decimalParts[1].Length);
}
else // negative exponent
{
if (positive)
result =
"0" +
decSeparator +
GetZeros(exponentValue + decimalParts[0].Replace("-", "").
Replace("+", "").Length) + newNumber;
else
result =
"-0" +
decSeparator +
GetZeros(exponentValue + decimalParts[0].Replace("-", "").
Replace("+", "").Length) + newNumber;
result = result.TrimEnd('0');
}
float temp = 0.00F;
if (float.TryParse(result, out temp))
{
return result;
}
throw new Exception();
}
private static string GetZeros(int zeroCount)
{
if (zeroCount < 0)
zeroCount = Math.Abs(zeroCount);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < zeroCount; i++) sb.Append("0");
return sb.ToString();
}
public static void Main(string[] args)
{
//Get Input Directory.
Console.WriteLine(#"Enter the Input Directory");
var readLine = Console.ReadLine();
if (readLine == null)
{
Console.WriteLine(#"Enter the input path properly.");
return;
}
var pathToInputDirectory = readLine.Trim();
//Get Output Directory.
Console.WriteLine(#"Enter the Output Directory");
readLine = Console.ReadLine();
if (readLine == null)
{
Console.WriteLine(#"Enter the output path properly.");
return;
}
var pathToOutputDirectory = readLine.Trim();
//Get Delimiter.
Console.WriteLine("Enter the delimiter;");
var columnDelimiter = (char)Console.Read();
//Loop over all files in the directory.
foreach (var inputFileName in Directory.GetFiles(pathToInputDirectory))
{
var outputFileWithouthNumbersInScientificNotation = string.Empty;
Console.WriteLine("Started operation on File : " + inputFileName);
if (File.Exists(inputFileName))
{
// Read the file
using (var file = new StreamReader(inputFileName))
{
string line;
while ((line = file.ReadLine()) != null)
{
String[] columns = line.Split(columnDelimiter);
var duplicateLine = string.Empty;
int lengthOfColumns = columns.Length;
int counter = 1;
foreach (var column in columns)
{
var columnDuplicate = column;
try
{
if (Regex.IsMatch(columnDuplicate.Trim(),
#"^[+-]?[0-9]+(\.[0-9]+)?[E]([+-]?[0-9]+)$",
RegexOptions.IgnoreCase))
{
Console.WriteLine("Regular expression matched for this :" + column);
columnDuplicate = ToLongString(Double.Parse
(column,
System.Globalization.NumberStyles.Float));
Console.WriteLine("Converted this no in scientific notation " +
"" + column + " to this number " +
columnDuplicate);
}
}
catch (Exception)
{
}
duplicateLine = duplicateLine + columnDuplicate;
if (counter != lengthOfColumns)
{
duplicateLine = duplicateLine + columnDelimiter.ToString();
}
counter++;
}
duplicateLine = duplicateLine + Environment.NewLine;
outputFileWithouthNumbersInScientificNotation = outputFileWithouthNumbersInScientificNotation + duplicateLine;
}
file.Close();
}
var outputFilePathWithoutNumbersInScientificNotation
= Path.Combine(pathToOutputDirectory, Path.GetFileName(inputFileName));
//Create Directory If it does not exist.
if (!Directory.Exists(pathToOutputDirectory))
Directory.CreateDirectory(pathToOutputDirectory);
using (var outputFile =
new StreamWriter(outputFilePathWithoutNumbersInScientificNotation))
{
outputFile.Write(outputFileWithouthNumbersInScientificNotation);
outputFile.Close();
}
Console.WriteLine("The transformed file is here :" +
outputFilePathWithoutNumbersInScientificNotation);
}
}
}
}
}
This code takes an input directory and based on the delimiter converts all values in scientific notation to numeric format.
Thanks
try this one:
public static string DoubleToFullString(double value,
NumberFormatInfo formatInfo)
{
string[] valueExpSplit;
string result, decimalSeparator;
int indexOfDecimalSeparator, exp;
valueExpSplit = value.ToString("r", formatInfo)
.ToUpper()
.Split(new char[] { 'E' });
if (valueExpSplit.Length > 1)
{
result = valueExpSplit[0];
exp = int.Parse(valueExpSplit[1]);
decimalSeparator = formatInfo.NumberDecimalSeparator;
if ((indexOfDecimalSeparator
= valueExpSplit[0].IndexOf(decimalSeparator)) > -1)
{
exp -= (result.Length - indexOfDecimalSeparator - 1);
result = result.Replace(decimalSeparator, "");
}
if (exp >= 0) result += new string('0', Math.Abs(exp));
else
{
exp = Math.Abs(exp);
if (exp >= result.Length)
{
result = "0." + new string('0', exp - result.Length)
+ result;
}
else
{
result = result.Insert(result.Length - exp, decimalSeparator);
}
}
}
else result = valueExpSplit[0];
return result;
}
Being millions of programmers world wide, it's always a good practice to try search if someone has bumped into your problem already. Sometimes there's solutions are garbage, which means it's time to write your own, and sometimes there are great, such as the following:
http://www.yoda.arachsys.com/csharp/DoubleConverter.cs
(details: http://www.yoda.arachsys.com/csharp/floatingpoint.html)
string strdScaleFactor = dScaleFactor.ToString(); // where dScaleFactor = 3.531467E-05
decimal decimalScaleFactor = Decimal.Parse(strdScaleFactor, System.Globalization.NumberStyles.Float);
I don't know if my answer to the question can still be helpful. But in this case I suggest the "decomposition of the double variable into decimal places" to store it in an Array / Array of data of type String.
This process of decomposition and storage in parts (number by number) from double to string, would basically work with the use of two loops and an "alternative" (if you thought of workaround, I think you got it), where the first loop will extract the values from double without converting to String, resulting in blessed scientific notation and storing number by number in an Array. And this will be done using MOD - the same method to check a palindrome number, which would be for example:
String[] Array_ = new double[ **here you will put an extreme value of places your DOUBLE can reach, you must have a prediction**];
for (int i = 0, variableDoubleMonstrous > 0, i++){
x = variableDoubleMonstrous %10;
Array_[i] = x;
variableDoubleMonstrous /= 10;
}
And the second loop to invert the Array values ​​(because in this process of checking a palindrome, the values ​​invert from the last place, to the first, from the penultimate to the second and so on. Remember?) to get the original value:
String[] ArrayFinal = new String[the same number of "places" / indices of the other Array / Data array];
int lengthArray = Array_.Length;
for (int i = 0, i < Array_.Length, i++){
FinalArray[i] = Array_[lengthArray - 1];
lengthArray--;
}
***Warning: There's a catch that I didn't pay attention to. In that case there will be no "." (floating point decimal separator or double), so this solution is not generalized. But if it is really important to use decimal separators, unfortunately the only possibility (If done well, it will have a great performance) is:
**Use a routine to get the position of the decimal point of the original value, the one with scientific notation - the important thing is that you know that this floating point is before a number such as the "Length" position x, and after a number such as the y position - extracting each digit using the loops - as shown above - and at the end "export" the data from the last Array to another one, including the decimal place divider (the comma, or the period , if variable decimal, double or float) in the imaginary position that was in the original variable, in the "real" position of that matrix.
*** The concept of position is, find out how many numbers occur before the decimal point, so with this information you will be able to store in the String Array the point in the real position.
NEEDS THAT CAN BE MADE:
But then you ask:
But what about when I'm going to convert String to a floating point value?
My answer is that you use the second matrix of this entire process (the one that receives the inversion of the first matrix that obtains the numbers by the palindrome method) and use it for the conversion, but always making sure, when necessary, of the position of the decimal place in future situations, in case this conversion (Double -> String) is needed again.
But what if the problem is to use the value of the converted Double (Array of Strings) in a calculation. Then in this case you went around in circles. Well, the original variable will work anyway even with scientific notation. The only difference between floating point and decimal variable types is in the rounding of values, which depending on the purpose, it will only be necessary to change the type of data used, but it is dangerous to have a significant loss of information, look here
I could be wrong, but isn't it like this?
data.ToString("n");
http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx
i think you need only to use IFormat with
ToString(doubleVar, System.Globalization.NumberStyles.Number)
example:
double d = double.MaxValue;
string s = d.ToString(d, System.Globalization.NumberStyles.Number);
My solution was using the custom formats.
try this:
double d;
d = 1234.12341234;
d.ToString("#########0.#########");
Just to build on what jcasso said what you can do is to adjust your double value by changing the exponent so that your favorite format would do it for you, apply the format, and than pad the result with zeros to compensate for the adjustment.
This works fine for me...
double number = 1.5E+200;
string s = number.ToString("#");
//Output: "150000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"

Making a simple calculator with arrays in C#

I am trying to make a simple calculator with arrays in C#. Firstly I tried making it using two integers and one operator only and it worked well. Now I am trying to do so that the user can make the expression as long as they like. For example 7 * 7 + 1 / 50 instead of a simple 9 + 8 which includes only one operator and two integers. The problem is that whenever I type a long expression with multiple numbers and operators it only calculates the first 2 numbers with the first operator. What is a good fix for this problem ? Thanks in advance.
static void Main()
{
while (true)
{
Console.WriteLine("Write an expression with two numbers and an operator with space in-between, for example, 4 + 2");
string expression;
string[] array;
string[] array1;
expression = Console.ReadLine();
array = expression.Split();
array1 = Calculation(array);
Console.WriteLine("Press ENTER to write a new expression.");
Console.ReadLine();
Console.Clear();
}
}
static string[] Calculation(string[] arr)
{
double numLeft= 0.0;
double numRight = 0.0;
string sign = "";
double result = 0.0;
int index = 1;
while (true)
{
numLeft = Convert.ToDouble(arr[0]);
sign = Convert.ToString(arr[index]);
numRight = Convert.ToDouble(arr[index + 1]);
index = index + 2;
if (sign == "+")
{
Console.Clear();
Console.WriteLine();
result= result + numLeft;
}
else if (sign == "-")
{
Console.Clear();
result = result + numLeft;
numLeft = 0 - numRight;
}
else if (sign == "*")
{
Console.Clear();
numLeft = numLeft * numRight;
}
else if (sign == "/")
{
Console.Clear();
numLeft = numLeft / numRight;
}
else
{
break;
}
result = result + numLeft;
Console.WriteLine("Answer: {0}", result);
return arr;
}
return arr;
}
because you return the array at the end of the "while true", so only first 2 get calculated.
Also, this will not be correct. for example: 2 + 3 * 4 = 14, and not 20, like your calculator will calculate.
How about this?
Split your operation string into pieces and fill a list with them;
7 * 7 + 1 / 50 => [7][*][7][+][1][/][50]
Then go through the list and solve the * and / operations. When you encounter one of the operators remove the operator element, the one before it and the one after it, and replace them with the result. Keep in mind that the list length changes.
first iteration => [49][+][1][/][50]
second iteration => [49][+][0.02]
Then do the same for + and - operators
first iteration => [49.02]
When you have only one element remaining in the list, that is your result.
For simple computations there exists a method in .net:
public static int Compute(string operation)
{
return new DataTable().Compute("7 * 7 + 1 / 50", null);
}
Source: C# Math calculator
If you really want to implement this I would suggest a recursive binary tree algorithm.
Pseudo-code:
1. Split incoming string on places where there is a mathematical operation symbol and turn in to a binary tree
2. Go through this tree and resolve operations that have a greater priority (* comes before +)
3. Recursion should return value of two child leafs and so on until it yields only one value to the main program
using System;
namespace _2nd_A_recap
{
class Program
{
static void Main(string[] args)
{
int result;
int a = 20, b = 10;
result = (a + b );
Console.WriteLine("Addition Opertaor:" + result);
result = (a - b);
Console.WriteLine("Subtraction Operator:" + result);
result = (a * b);
Console.WriteLine("Multiplication Operator:" + result);
result = (a / b);
Console.WriteLine("Division Operator:" + result);
result = (a % b);
Console.WriteLine("Modulus Operator:" + result);
Console.WriteLine("Press enter to end Calculator...");
Console.ReadKey();
}
}
}

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];

C# convert formatted string (31.2k) back to number (31240)

Let's say I have this code:
int i = 31240;
string Number = ((double)i / 1000).ToString("0.#k");
I get this result as a string for Number: 31,2k
And now, I wanna do the exact opposite, that is to take this string "31,2k" and take it back to 31240 or even to 31200, but I don't know how to do...
Any idea?
Someone said that was impossible.
BUT Finally I found the perfect way to achieve my goal. I post the solution for those who could be willing to know.
The use is simple, and it allows to make 2 kind of conversions:
Thousands, Example: 45831 <=> 45,8k <=> 45831
Millions, Example: 123852376 <=> 123,5m <=> 123852376
int i = (int)(Double.Parse(Number.Substring(0, Number.Length - 1)) * 1000);
We remove the k with Number.Substring(0, Number.Length - 1), transform it to double with Double.Parse, multiply by 1000 and in the end convert to int. The order of the things is very important! The first time I was doing (int)Double.Parse(Number.Substring(0, Number.Length - 1)) * 1000 that was converting to int before multiplying (so I got 31000 instead of 31200)
I'll add that if I had to write that code, I would sleep VERY much better if I used the Decimal.Parse instead of the Double.Parse (so I would be sure against the vagaries of floating points)
I'll add a better method:
int i2 = int.Parse(Number.Substring(0, Number.Length - 1).Replace(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator, string.Empty)) * 100;
This is much more interesting. We remove the k as in the other method but this time we remove the , from the string too and we multiply by 100.
The interesting trick is that instead of simply ("bovinamente" in italian slang, as bovines would do) replace the , with an empty string, we get the current decimal separator (CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator) and we replace THAT with an empty string.
Clearly had we used another culture in composing the original string (for example the always good CultureInfo.InvariantCulture) we would use that to get the NumberDecimalSeparator
Here is the solution I went through:
public class StringFromInt
{
public enum FormatStyle
{
Kilo = 1000,
Mega = 1000000
}
public int Number;
public FormatStyle Format
{
get
{
switch (LimitValueBeforeConversion)
{
case 1000: return FormatStyle.Kilo;
case 1000000: return FormatStyle.Mega;
default:
throw new NotImplementedException("You must implement the code for this kind of value");
}
}
set
{
if (value == FormatStyle.Kilo)
{
LimitValueBeforeConversion = 1000;
}
else if (value == FormatStyle.Mega)
{
LimitValueBeforeConversion = 1000000;
}
}
}
public int LimitValueBeforeConversion
{ get; set; }
public static implicit operator int(StringFromInt s)
{
return s.Number;
}
public static implicit operator StringFromInt(int number)
{
StringFromInt s = new StringFromInt(number);
return s;
}
#region Constructors
public StringFromInt(int number, FormatStyle format)
{
this.Number = number;
Format = format;
}
public StringFromInt(int number)
: this(number, FormatStyle.Kilo)
{
if (number >= 1000000)
{
this.Format = FormatStyle.Mega;
}
}
#endregion
public override string ToString()
{
if (Number >= LimitValueBeforeConversion)
{
string formatString = "0.#k";
switch (Format)
{
case FormatStyle.Kilo:
formatString = "0.#k";
break;
case FormatStyle.Mega:
formatString = "0.#m";
break;
default:
throw new NotImplementedException("You must implement the code for this kind of value");
}
return ((double)Number / LimitValueBeforeConversion).ToString(formatString);
}
else
{
return Number.ToString();
}
}
}
And here is a test program:
class Program
{
static void Main(string[] args)
{
int i = 31240;
string StringRepresentation = ((double)i / 1000).ToString("0.#k");
int resultBackWithParse = int.Parse(StringRepresentation.Substring(0, StringRepresentation.Length - 1).Replace(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator, string.Empty)) * 100;
Console.WriteLine("Base number: " + i.ToString());
Console.WriteLine(new string('-', 35));
Console.WriteLine("String representation: " + StringRepresentation);
Console.WriteLine("Int representation With Int.Parse: " + resultBackWithParse.ToString());
Console.WriteLine();
StringFromInt MySolutionNumber = i;
int resultBackWithStringFromInt = MySolutionNumber;
Console.WriteLine("String representation With StringFromInt: " + MySolutionNumber.ToString());
Console.WriteLine("Int representation With StringFromInt: " + resultBackWithStringFromInt);
Console.WriteLine(new string('=', 35) + "\n");
i = 123456789;
StringFromInt MyNumber = 123456789;
int resultBack = MyNumber;
Console.WriteLine("Base number: " + i.ToString());
Console.WriteLine(new string('-', 35));
Console.WriteLine("String representation With StringFromInt: " + MyNumber);
Console.WriteLine("Int representation With StringFromInt: " + resultBack);
Console.ReadKey(true);
}
}
As you can notice, there is no need to use the "new" initializer, I mean no need to do:
StringFromInt Number = new StringFromInt(YourNumber)
Thanks to the implicit operator, you can do:
StringFromInt Number = YourNumber
I don't know, but I think it's a good beginning, what do you think?
Anyway, I managed to do what I wanted, so for people who thought it couldn't be done, you see, that's possible :-)
Obviously this can be improved: this version works for thousands and millions only.
Greetings

Categories

Resources