Datagridview cell tooltip word wrap - c#

I have a datagridview which have very long string in one column. When I hover mouse over it the default, one line, tooltip is not enough to display whole content. Any ideas how to word wrap text in datagridview tooltip?

Try this example:
private void dgvProducts_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if ((e.ColumnIndex == dgvProducts.Columns["colDescription"].Index) && e.Value != null)
{
DataGridViewCell cell = dgvProducts.Rows[e.RowIndex].Cells[e.ColumnIndex];
cell.ToolTipText = String.Join(Environment.NewLine, e.Value.ToString().DivideLongString());
}
}
//-------------- Extension Methods ------------- C# 6.0
using static System.String;
public static class Extensions
{
public static string[] DivideLongString(this string text, int length = 10)
{
if (text.Length <= length) return new[] { text };
var words = text.GetTotalWords();
var output = new string[(words.Length % length > 1 ? words.Length / length + 1 : words.Length % length < 1 ? words.Length / length - 1 : words.Length / length) + 100];
var oIndex = 0;
var wIndex = length - 1;
try
{
for (var i = 0; i < words.Length; i++)
{
if (wIndex < i)
{
wIndex += length - 1;
oIndex++;
}
output[oIndex] += $"{words[i]} ";
}
if (output.Length > 2 && !IsNullOrEmpty(output[output.Length - 1]) && output[output.Length - 1].CountWords() < 3)
{
output[output.Length - 2] += output[output.Length - 1];
output[output.Length - 1] = Empty;
}
return output.Where(val => !IsNullOrEmpty(val)).ToArray();
}
catch (Exception ex)
{
ExceptionLogger.Log(ex);
return output.Where(val => !IsNullOrEmpty(val)).ToArray();
}
}
public static string ReplaceMultipleSpacesWith(this string text, string newString)
{
return Regex.Replace(text, #"\s+", newString);
}
public static string[] GetTotalWords(this string text)
{
text = text.Trim().ReplaceMultipleSpacesWith(" ");
var words = text.Split(' ');
return words;
}
}

Try this - it works for me:
private void dataGridView1_CellMouseEnter(object sender, DataGridViewCellEventArgs e)
{
int wrapLen = 84;
if ((e.RowIndex >= 0) && e.ColumnIndex >= 0)
{
DataGridViewCell cell = this.dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex];
string cellText = cell.Value.ToString();
if (cellText.Length >= wrapLen)
{
cell.ToolTipText = "";
int n = cellText.Length / wrapLen;
for (int i = 0; i <= n; i++)
{
int wStart = wrapLen * i;
int wEnd = wrapLen * (i + 1);
if (wEnd >= cellText.Length)
wEnd = cellText.Length;
cell.ToolTipText += cellText.Substring(wStart, wEnd - wStart) + "\n";
}
}
}
}

Related

C# Calculator "Input string was not in a correct format" on every operation except addition

I tried to create a small calculator and everything worked just fine. I could do every operation without an error. Then I tried to improve some things and add some.
Out of a sudden the original Part does not work anymore and i get the Error:[ System.FormatException: "Input string was not in a correct format." ] every time i try to substract, multiply or divide.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Calculator_V2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void OnKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
answer.Text = Calculate(textBox.Text);
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
string s_button = sender.ToString();
textBox.Text = textBox.Text + s_button.Substring(s_button.Length - 1);
}
public string Calculate(string text)
{
double finalAnswer = AddAndSubstract(text);
return finalAnswer.ToString();
}
public double AddAndSubstract(string text1)
{
string[] text = text1.Split('-');
List<string> textList = new List<string>();
for (int i = 0; i < text.Length; i++)
{
textList.Add(text[i]);
if (i != text.Length - 1)
{
textList.Add("-");
}
textList.Add("-");
}
for (int i = 0; i < textList.Count; i++)
{
if (textList[i].Contains('+') && textList[i].Length > 1)
{
string[] testPart = textList[i].Split('+');
textList.RemoveAt(i);
for (int j = testPart.Length - 1; j >= 0; j--)
{
textList.Insert(i, testPart[j]);
if (j != 0)
{
textList.Insert(i, "+");
}
}
}
}
double total;
if (textList[0].Contains("*") || textList[0].Contains("/"))
{
total = DivideAndMultiply(textList[0]);
return total;
}
else
{
total = Convert.ToDouble(textList[0]);
for (int i = 2; i < textList.Count; i += 2)
{
if (textList[i - 1] == "-")
{
total = total - DivideAndMultiply(textList[i]);
}
else if (textList[i - 1] == "+")
{
total = total + DivideAndMultiply(textList[i]);
}
}
return total;
}
}
public double DivideAndMultiply(string text1)
{
string[] text = text1.Split('*');
List<string> textList = new List<string>();
for (int i = 0; i < text.Length; i++)
{
textList.Add(text[i]);
if (i != text.Length - 1)
{
textList.Add("*");
}
textList.Add("*");
}
for (int i = 0; i < textList.Count; i++)
{
if (textList[i].Contains('/') && textList[i].Length > 1)
{
string[] testPart = textList[i].Split('/');
textList.RemoveAt(i);
for (int j = testPart.Length - 1; j >= 0; j--)
{
textList.Insert(i, testPart[j]);
if (j != 0)
{
textList.Insert(i, "/");
}
}
}
}
double total = Convert.ToDouble(textList[0]);
for (int i = 2; i < textList.Count; i += 2)
{
if (textList[i - 1] == "/")
{
total = total / Convert.ToDouble(textList[i]);
}
else if (textList[i - 1] == "*")
{
total = total * Convert.ToDouble(textList[i]);
}
}
return total;
}
private void Button_Click_C(object sender, RoutedEventArgs e)
{
double finalAnswer = 0;
answer.Text = "";
textBox.Text = "";
}
private void Button_Click_zahl(object sender, RoutedEventArgs e)
{
string s_button = sender.ToString();
textBox.Text = textBox.Text + s_button.Substring(s_button.Length - 1);
}
private void Button_Click_equals(object sender, RoutedEventArgs e)
{
answer.Text = RemoveBrackets(textBox.Text);
}
public string RemoveBrackets(string text)
{
while (text.Contains('(') && text.Contains(')'))
{
int openIndex = 0;
int closeIndex = 0;
for (int i = 0; i < text.Length; i++)
{
if (text[i] == '(')
{
openIndex = i;
}
if (text[i] == ')')
{
closeIndex = i;
text = text.Remove(openIndex,closeIndex-openIndex +1).Insert(openIndex,ResolveBrackets(openIndex, closeIndex, text));
break;
}
}
}
for (int i = 1; i < text.Length; i++)
{
if (text[i] == '-' && (text[i]-1=='*' || text[i] - 1 == '/'))
{
for (int j=i-1; j>=0; j++)
{
if (text[j] == '+')
{
StringBuilder text1 = new StringBuilder(text);
text1[j] = '-';
text = text1.ToString();
text = text.Remove(i, 1);
break;
}
else if (text[j] == '-')
{
StringBuilder text1 = new StringBuilder(text);
text1[j] = '+';
text = text1.ToString();
text = text.Remove(i, 1);
break;
}
}
}
}
if (text[0] == '-') //für Fehler wenn - als erste Ziffer
{
text = '0' + text;
}
return Calculate(text);
}
public string ResolveBrackets(int openIndex, int closeIndex, string text)
{
string bracketAnswer = Calculate(text.Substring(openIndex +1, closeIndex -1));
return bracketAnswer;
}
}
}
Because you probably add the minus character twice
if (i != text.Length - 1)
{
textList.Add("-");
}
textList.Add("-");
Then, when you loop in step of 2
for (int i = 2; i < textList.Count; i += 2)
You don't have [number] [sign] [number] [sign] anymore.
I suggest you look and the items in your list to see the problem. I would also suggest that you split your logic into smaller methods that could individually be tested.
i think the problem is your use of
double total = Convert.ToDouble(textList[0]);
in DivideAndMultiply
First of all it's best practice to test if the string is null or empty using String.IsNullOrEmpty(textList[0]); and use Double.TryParse instead of convert.

Why Is This Code Running Longer Character Combinations Than Necessary?

I'm a math student with little to no experience programming, but I wrote this to act like a brute force algorithm. It seems to run fine except that it runs all the password combinations out to 3 characters for passwords as short as 2. Also I'm sure there's a way to refactor the for and if statements as well. Any help would be appreciated, thanks.
I've already been testing to see if some of the if statements aren't executing, and it looks like the statements with "console.writeln(Is this executing)" aren't executing but I'm not really sure.
public Form1()
{
InitializeComponent();
}
static char[] Match ={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j' ,'k','l','m','n','o','p',
'q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','C','L','M','N','O','P',
'Q','R','S','T','U','V','X','Y','Z','!','?',' ','*','-','+'};
private string[] tempPass;
private void button1_Click(object sender, EventArgs e)
{
string tempPass1 = "lm";
string result = String.Empty;
int passLength = 1;
int maxLength = 17;
tempPass = new string[passLength];
for (int i = 0; i < Match.Length; i++)
{
if (tempPass1 != result)
{
tempPass[0] = Match[i].ToString();
result = String.Concat(tempPass);
if (passLength > 1)
{
for (int j = 0; j < Match.Length; j++)
{
if (tempPass1 != result)
{
tempPass[1] = Match[j].ToString();
result = String.Concat(tempPass);
if (passLength > 2)
{
for (int k = 0; k < Match.Length; k++)
{
if (tempPass1 != result)
{
tempPass[2] = Match[k].ToString();
result = String.Concat(tempPass);
if (tempPass[0] == "+" && tempPass[1] == "+" && tempPass[2] == "+" && tempPass1 != result)
{
Console.WriteLine("This will execute?");
passLength++;
tempPass = new string[passLength];
k = 0;
j = 0;
i = 0;
}
else if (result == tempPass1)
{
Console.WriteLine("Broken");
Console.WriteLine("This is big gay: " + result);
break;
}
}
}
}
if (tempPass[0] == "+" && tempPass[1] == "+" && tempPass1 != result)
{
Console.WriteLine("Did this execute?");
passLength++;
tempPass = new string[passLength];
j = 0;
i = 0;
}
else if (result == tempPass1)
{
Console.WriteLine("Broken");
Console.WriteLine("This is bigger gay: " + result);
break;
}
}
}
}
//tempPass[1] = "World!";
//Console.WriteLine(result);
if (tempPass[tempPass.Length - 1] == "+" && tempPass1 != result)
{
passLength++;
tempPass = new string[passLength];
Console.WriteLine(tempPass.Length + " " + result + " " + "Success");
Console.WriteLine(i);
i = 0; /**update
j = 0;
k = 0;
l = 0;
m = 0;*/
}
else if (result == tempPass1)
{
Console.WriteLine("Broken");
Console.WriteLine("This is biggest gay: " + result);
}
}
}
}
Play with this; modified from my answer here. It'll show you all the 2 and 3 length combinations. Clicking the button will start/stop the generation process. You need a button, label, and a timer:
public partial class Form1 : Form
{
private Revision rev;
public Form1()
{
InitializeComponent();
rev = new Revision("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!? *-+", "00");
label1.Text = rev.CurrentRevision;
}
private void button1_Click(object sender, EventArgs e)
{
timer1.Enabled = !timer1.Enabled;
}
private void timer1_Tick(object sender, EventArgs e)
{
rev.NextRevision();
if (rev.CurrentRevision.Length == 4)
{
timer1.Stop();
MessageBox.Show("Sequence Complete");
// make it start back at the beginning?
rev = new Revision("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!? *-+", "00");
label1.Text = rev.CurrentRevision;
}
else
{
label1.Text = rev.CurrentRevision;
}
}
}
public class Revision
{
private string chars;
private char[] values;
private System.Text.StringBuilder curRevision;
public Revision()
{
this.DefaultRevision();
}
public Revision(string validChars)
{
if (validChars.Length > 0)
{
chars = validChars;
values = validChars.ToCharArray();
curRevision = new System.Text.StringBuilder(values[0]);
}
else
{
this.DefaultRevision();
}
}
public Revision(string validChars, string startingRevision)
: this(validChars)
{
curRevision = new System.Text.StringBuilder(startingRevision.ToUpper());
int i = 0;
for (i = 0; i <= curRevision.Length - 1; i++)
{
if (Array.IndexOf(values, curRevision[i]) == -1)
{
curRevision = new System.Text.StringBuilder(values[0]);
break;
}
}
}
private void DefaultRevision()
{
chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
values = chars.ToCharArray();
curRevision = new System.Text.StringBuilder(values[0]);
}
public string ValidChars
{
get { return chars; }
}
public string CurrentRevision
{
get { return curRevision.ToString(); }
}
public string NextRevision(int numRevisions = 1)
{
bool forward = (numRevisions > 0);
numRevisions = Math.Abs(numRevisions);
int i = 0;
for (i = 1; i <= numRevisions; i++)
{
if (forward)
{
this.Increment();
}
else
{
this.Decrement();
}
}
return this.CurrentRevision;
}
private void Increment()
{
char curChar = curRevision[curRevision.Length - 1];
int index = Array.IndexOf(values, curChar);
if (index < (chars.Length - 1))
{
index = index + 1;
curRevision[curRevision.Length - 1] = values[index];
}
else
{
curRevision[curRevision.Length - 1] = values[0];
int i = 0;
int startPosition = curRevision.Length - 2;
for (i = startPosition; i >= 0; i += -1)
{
curChar = curRevision[i];
index = Array.IndexOf(values, curChar);
if (index < (values.Length - 1))
{
index = index + 1;
curRevision[i] = values[index];
return;
}
else
{
curRevision[i] = values[0];
}
}
curRevision.Insert(0, values[0]);
}
}
private void Decrement()
{
char curChar = curRevision[curRevision.Length - 1];
int index = Array.IndexOf(values, curChar);
if (index > 0)
{
index = index - 1;
curRevision[curRevision.Length - 1] = values[index];
}
else
{
curRevision[curRevision.Length - 1] = values[values.Length - 1];
int i = 0;
int startPosition = curRevision.Length - 2;
for (i = startPosition; i >= 0; i += -1)
{
curChar = curRevision[i];
index = Array.IndexOf(values, curChar);
if (index > 0)
{
index = index - 1;
curRevision[i] = values[index];
return;
}
else
{
curRevision[i] = values[values.Length - 1];
}
}
curRevision.Remove(0, 1);
if (curRevision.Length == 0)
{
curRevision.Insert(0, values[0]);
}
}
}
}

How to increment mixed Alphanumeric in C#?

I have requirements in a project to generate sequential rows and columns which are alphanumeric values.
The end user will pass the start value of row and column he would like to start from, and how many rows and columns he wants to generate.
For letters the max value is Z
For numbers the max values is 9
If the end user passed these parameters:
StartRow = 0A
StartColumn = A9Z
rowsCount = 2
columnsCount = 5
I would like to get this result:
You might want to reconsider your approach. Rather than maintaining an alphanumeric value and trying to increment it, maintain the value as a class containing Row and Column values, and then use ToString to convert it to the alphanumeric representation. Like this:
class RowCol
{
private int _row;
private int _col;
public int Row
{
get { return _row; }
set
{
// Row is of the form <digit><letter
// giving you 260 possible values.
if (value < 0 || value > 259)
throw new ArgumentOutOfRangeException();
_row = value;
}
}
public int Col
{
get { return _col; }
set
{
// Col is <letter><digit><letter>,
// giving you 6,760 possible values
if (value < 0 || value > 6759)
throw new ArgumentOutOfRangeException();
_col = value;
}
}
public string RowString
{
get
{
// convert Row value to string
int r, c;
r = Math.DivMod(_row, 26, out c);
r += '0';
c += 'A';
return string.Concat((char)r, (char)c);
}
set
{
// convert string to number.
// String is of the form <letter><digit>
if (string.IsNullOrEmpty(value) || value.Length != 2
|| !Char.IsDigit(value[0] || !Char.IsUpper(value[1]))
throw new ArgumentException();
_row = 26*(value[0]-'0') + (value[1]-'A');
}
}
public string ColString
{
get
{
int left, middle, right remainder;
left = Math.DivRem(_col, 260, out remainder);
middle = Math.DivRem(remainder, 26, out right);
left += 'A';
middle += '0';
right += 'A';
return string.Concat((char)left, (char)middle, (char)right);
}
set
{
// Do standard checking here to make sure it's in the right form.
if (string.IsNullOrEmpty(value) || value.Length != 3
|| !Char.IsUpper(value[0] || !Char.IsDigit(value[1]) || !Char.IsUpper(value[2]))
throw new ArgumentException();
_col = 260*(value[0] - 'A');
_col += 26*(value[1] - '0');
_col += value[2] - 'A';
}
}
public override string ToString()
{
return RowString + '-' + ColString;
}
public RowCol(int row, int col)
{
Row = _row;
Col = _col;
}
public RowCol(string row, string col)
{
RowString = row;
RowString = col;
}
}
(Code not yet tested, but that's the general idea.)
That's a bit more code than you have, it hides the complexity in the RowCol class rather than forcing you to deal with it in your main program logic. The point here is that you just want to increment the row or column; you don't want to have to think about how that's done. It makes your main program logic easier to understand. For example:
string startRow = "0A";
string startCol = "B0A";
RowCol rc = new RowCol("0A", "B0A");
for (int r = 0; r < rowsCount; r++)
{
rc.ColString = "B0A";
for (int c = 0; c < columnsCount; c++)
{
Console.WriteLine(rc);
rc.Row = rc.Row + 1;
}
rc.Col = rc.Col + 1;
}
By casting this as a simple conversion problem and encapsulating it in a class, I've made the code more robust and flexible, and easier to test, understand, and use.
I have come up with very simple solution to implement that and I would like to share this Console application :
class Program
{
static void Main(string[] args)
{
var row = "0A";
var column = "A9Z";
var rowsCount = 2;
var columnsCount = 5;
var rowCharArray =row.ToArray().Reverse().ToArray();
var columnCharArray = column.ToArray().Reverse().ToArray();
for (int i = 0; i < rowsCount; i++)
{
for (int j = 0; j < columnsCount; j++)
{
columnCharArray = incrementChar(columnCharArray);
var currentColumn = string.Join("", columnCharArray.Reverse().ToArray());
var currentRow= string.Join("", rowCharArray.Reverse().ToArray());
Console.WriteLine(currentRow + "-" + currentColumn);
}
columnCharArray = column.ToArray().Reverse().ToArray();
rowCharArray= incrementChar(rowCharArray);
Console.WriteLine("-------------------------------");
}
Console.ReadLine();
}
static char[] incrementChar(char[] charArray,int currentIndex=0)
{
char temp = charArray[currentIndex];
if (charArray.Length -1 == currentIndex && (temp == '9' || temp == 'Z'))
throw new Exception();
temp++;
if(Regex.IsMatch(temp.ToString(),"[A-Z]"))
{
charArray[currentIndex] = temp;
}
else
{
if (Regex.IsMatch(temp.ToString(), "[0-9]"))
{
charArray[currentIndex] = temp;
}
else
{
currentIndex++;
incrementChar(charArray, currentIndex);
}
}
if (currentIndex != 0)
charArray = resetChar(charArray, currentIndex);
return charArray;
}
static char[] resetChar(char[] charArray,int currentIndex)
{
for (int i = 0; i < currentIndex; i++)
{
if (charArray[i] == 'Z')
charArray[i] = 'A';
else if (charArray[i] == '9')
charArray[i] = '0';
}
return charArray;
}
}

Adding exponentials

I made an expression evaluator but I only included: addition and substraction and multiply and division and a brackets resolver and I want to add exponential "^" and after that trigonometric functions: sine, cosine and tangent but I don't know where to start... this is what I did for now:
public static string RemoveBrackets(string text)
{
while (text.Contains('(') && text.Contains(')'))
{
int openIndex = 0;
int closeIndex = 0;
for(int i = 0; i < text.Length; ++i)
{
if(text[i] == '(')
{
openIndex = i;
}
if(text[i] == ')')
{
closeIndex = i;
text = text.Remove(openIndex, closeIndex - openIndex + 1).Insert(openIndex, ResolveBrackets(openIndex, closeIndex, text));
break;
}
}
}
for(int i = 1; i < text.Length; ++i)
{
if(text[i] == '-' && (text[i - 1] == '*' || text[i - 1] == '/'))
{
for(int j = i - 1; j >= 0; --j)
{
if(text[j] == '+')
{
StringBuilder text1 = new StringBuilder(text);
text1[j] = '-';
text = text1.ToString();
text = text.Remove(i, 1);
break;
}
else if(text[j] == '-')
{
StringBuilder text1 = new StringBuilder(text);
text1[j] = '+';
text = text1.ToString();
text = text.Remove(i, 1);
break;
}
}
}
}
for (int i = 0; i < text.Length; ++i)
{
if (text[i] == '-' && (text[i - 1] == '-' || text[i - 1] == '+'))
{
if(text[i - 1] == '-')
{
StringBuilder text1 = new StringBuilder(text);
text1[i] = '+';
text = text1.ToString();
text = text.Remove(i - 1, 1);
}
else
{
StringBuilder text1 = new StringBuilder(text);
text1[i] = '-';
text = text1.ToString();
text = text.Remove(i - 1, 1);
}
}
else if (text[i] == '+' && (text[i - 1] == '-' || text[i - 1] == '+'))
{
if (text[i - 1] == '-')
{
StringBuilder text1 = new StringBuilder(text);
text1[i] = '-';
text = text1.ToString();
text = text.Remove(i - 1, 1);
}
else
{
StringBuilder text1 = new StringBuilder(text);
text1[i] = '+';
text = text1.ToString();
text = text.Remove(i - 1, 1);
}
}
}
if (text[0] == '-')
{
text = '0' + text;
}
return Calculate(text);
}
public static string ResolveBrackets(int openindex, int closeindex, string text)
{
string BracketAnswer = evaluate(text.Substring(openindex + 1, closeindex - openindex - 1));
return BracketAnswer;
}
public static double DivideAndMultiply(string text)
{
string[] expr = text.Split('*');
List<string> textList = new List<string>();
for (int i = 0; i < expr.Length; ++i)
{
textList.Add(expr[i]);
if (i != expr.Length - 1)
{
textList.Add("*");
}
}
for (int i = 0; i < textList.Count; ++i)
{
if (textList[i].Contains('/') && textList[i].Length > 1)
{
string[] textPart = textList[i].Split('/');
textList.RemoveAt(i);
for (int j = textPart.Length - 1; j >= 0; --j)
{
textList.Insert(i, textPart[j]);
if (j != 0)
{
textList.Insert(i, "/");
}
}
}
}
double total;
if (textList[0].Contains('*') || textList[0].Contains('/'))
{
total = textList[0] == "" ? 0 : DivideAndMultiply(textList[0]);
}
else
{
total = Convert.ToDouble(textList[0]);
}
/// 7:30 min tutorial
for (int i = 2; i < textList.Count; i += 2)
{
if (textList[i - 1] == "/")
{
total /= Convert.ToDouble(textList[i]);
}
else if (textList[i - 1] == "*")
{
total *= Convert.ToDouble(textList[i]);
}
}
return total;
}
public static double AddAndSubstract(string text)
{
string[] expr = text.Split('-');
List<string> textList = new List<string>();
for(int i = 0; i < expr.Length; ++i)
{
textList.Add(expr[i]);
if(i != expr.Length - 1)
{
textList.Add("-");
}
}
for(int i = 0; i < textList.Count; ++i)
{
if (textList[i].Contains('+') && textList[i].Length > 1)
{
string[] textPart = textList[i].Split('+');
textList.RemoveAt(i);
for (int j = textPart.Length - 1; j >= 0; --j)
{
textList.Insert(i, textPart[j]);
if (j != 0)
{
textList.Insert(i, "+");
}
}
}
}
//double total = Add(expr[0]);
double total = expr[0] == "" ? 0 : DivideAndMultiply(textList[0]);
for (int i = 2; i < textList.Count; i += 2)
{
if(textList[i - 1] == "-")
{
total -= DivideAndMultiply(textList[i]);
}
else if(textList[i - 1] == "+")
{
total += DivideAndMultiply(textList[i]);
}
}
return total;
}
Any suggestions on what should I read?
Use system.math to do this, it is easier
read about programmatic part - of math class
https://msdn.microsoft.com/en-us/library/system.math(v=vs.110).aspx
And find some tuturial about scientific calculator. That should give a insights.

How to add or subtract very large numbers without bigint in C#?

So let me start by saying that I'm a newbie with little to moderate knowledge about C#.
Coming to the topic: I need to make a program that is able to add/subtract very large integers. Initially, used BigInt only to find out it's not allowed. There should be a logical workaround for this? I have an idea which is using "elementary school method" where you add each digit starting from right to left.
I made a string which I split into char array and added each digit from right to left(GetUpperBound-i). But it doesn't seem to work.
My Code:
string s, s2;
char[] c_arr, c_arr2;
int i, erg;
s = "1234";
s2 = "5678";
c_arr = s.ToCharArray();
c_arr2 = s2.ToCharArray();
for (i = 0; i <= c_arr.GetUpperBound(0); i++)
{
erg = c_arr[c_arr.GetUpperBound(0)-i]+c_arr2[c_arr2.GetUpperBound(0)-i];
Console.Write(erg);
}
Console.ReadKey();
There are a few things wrong with your code for the 'elementary school method'. You don't account for carry, you're adding up ascii values rather than actual values between 0-9, and you're outputting the results in the wrong order.
The code below, whilst not very elegant, does produce the correct results:
var s1 = "12345";
var s2 = "5678";
var carry = false;
var result = String.Empty;
if(s1.Length != s2.Length)
{
var diff = Math.Abs(s1.Length - s2.Length);
if(s1.Length < s2.Length)
{
s1 = String.Join("", Enumerable.Repeat("0", diff)) + s1;
}
else
{
s2 = String.Join("", Enumerable.Repeat("0", diff)) + s2;
}
}
for(int i = s1.Length-1;i >= 0; i--)
{
var augend = Convert.ToInt32(s1.Substring(i,1));
var addend = Convert.ToInt32(s2.Substring(i,1));
var sum = augend + addend;
sum += (carry ? 1 : 0);
carry = false;
if(sum > 9)
{
carry = true;
sum -= 10;
}
result = sum.ToString() + result;
}
if(carry)
{
result = "1" + result;
}
Console.WriteLine(result);
The following program can be used to add two large numbers, I have used string builder to store the result. You can add numbers containing digits upto '2,147,483,647'.
Using System;
using System.Text;
using System.Linq;
public class Test
{
public static void Main()
{
string term1="15245142151235123512352362362352351236";
string term2="1522135123612646436143613461344";
StringBuilder sum=new StringBuilder();
int n1=term1.Length;
int n2=term2.Length;
int carry=0;
int n=(n1>n2)?n1:n2;
if(n1>n2)
term2=term2.PadLeft(n1,'0');
else
term1=term1.PadLeft(n2,'0');
for(int i=n-1;i>=0;i--)
{
int value=(carry+term1[i]-48+term2[i]-48)%10;
sum.Append(value);
carry=(carry+term1[i]-48+term2[i]-48)/10;
}
char[] c=sum.ToString().ToCharArray();
Array.Reverse(c);
Console.WriteLine(c);
}
}
string Add(string s1, string s2)
{
bool carry = false;
string result = string.Empty;
if(s1[0] != '-' && s2[0] != '-')
{
if (s1.Length < s2.Length)
s1 = s1.PadLeft(s2.Length, '0');
if(s2.Length < s1.Length)
s2 = s2.PadLeft(s1.Length, '0');
for(int i = s1.Length-1; i >= 0; i--)
{
var augend = Convert.ToInt64(s1.Substring(i,1));
var addend = Convert.ToInt64(s2.Substring(i,1));
var sum = augend + addend;
sum += (carry ? 1 : 0);
carry = false;
if(sum > 9)
{
carry = true;
sum -= 10;
}
result = sum.ToString() + result;
}
if(carry)
{
result = "1" + result;
}
}
else if(s1[0] == '-' || s2[0] == '-')
{
long sum = 0;
if(s2[0] == '-')
{
//Removing negative sign
char[] MyChar = {'-'};
string NewString = s2.TrimStart(MyChar);
s2 = NewString;
if(s2.Length < s1.Length)
s2 = s2.PadLeft(s1.Length, '0');
for (int i = s1.Length - 1; i >= 0; i--)
{
var augend = Convert.ToInt64(s1.Substring(i,1));
var addend = Convert.ToInt64(s2.Substring(i,1));
if(augend >= addend)
{
sum = augend - addend;
}
else
{
int temp = i - 1;
long numberNext = Convert.ToInt64(s1.Substring(temp,1));
//if number before is 0
while(numberNext == 0)
{
temp--;
numberNext = Convert.ToInt64(s1.Substring(temp,1));
}
//taking one from the neighbor number
int a = int.Parse(s1[temp].ToString());
a--;
StringBuilder tempString = new StringBuilder(s1);
string aString = a.ToString();
tempString[temp] = Convert.ToChar(aString);
s1 = tempString.ToString();
while(temp < i)
{
temp++;
StringBuilder copyS1 = new StringBuilder(s1);
string nine = "9";
tempString[temp] = Convert.ToChar(nine);
s1 = tempString.ToString();
}
augend += 10;
sum = augend - addend;
}
result = sum.ToString() + result;
}
//Removing the zero infront of the answer
char[] zeroChar = {'0'};
string tempResult = result.TrimStart(zeroChar);
result = tempResult;
}
}
return result;
}
string Multiply(string s1, string s2)
{
string result = string.Empty;
//For multipication
bool Negative = false;
if(s1[0] == '-' && s2[0] == '-')
Negative = false;
else if(s1[0] == '-' || s2[0] == '-')
Negative = true;
char[] minusChar = {'-'};
string NewString;
NewString = s2.TrimStart(minusChar);
s2 = NewString;
NewString = s1.TrimStart(minusChar);
s1 = NewString;
List<string> resultList = new List<string>();
for(int i = s2.Length - 1; i >= 0; i--)
{
string multiplycation = string.Empty;
for (int j = s1.Length - 1; j >= 0; j--)
{
var augend = Convert.ToInt64(s1.Substring(j,1));
var addend = Convert.ToInt64(s2.Substring(i,1));
long multiply = augend * addend;
// print(multiply);
multiplycation = multiply.ToString() + multiplycation;
}
//Adding zero at the end of the multiplication
for (int k = s2.Length - 1 - i; k > 0; k--)
{
multiplycation += "0";
}
resultList.Add(multiplycation);
}
for (int i = 1; i < resultList.Count; i++)
{
resultList[0] = Add(resultList[0],resultList[i]);
}
//Finally assigning if negative negative sign in front of the number
if(Negative)
result = resultList[0].Insert(0,"-");
else
result = resultList[0];
return result;
}
string Divide(string dividend, string divisor)
{
string result = string.Empty;
int remainder = 0;
int intNumberstoGet = divisor.Length;
int currentInt = 0;
int dividing = int.Parse(dividend.Substring(currentInt,intNumberstoGet));
int intDivisor = int.Parse(divisor);
while(currentInt < dividend.Length)
{
if(dividing == 0)
{
currentInt++;
result += "0";
}
else
{
while(dividing < intDivisor)
{
intNumberstoGet++;
dividing = int.Parse(dividend.Substring(currentInt,intNumberstoGet));
}
if (dividing > 0)
{
remainder = dividing % intDivisor;
result += ((dividing - remainder) / intDivisor).ToString();
intNumberstoGet = 1;
if(currentInt < dividend.Length - 2)
currentInt += 2;
else
currentInt++;
if(currentInt != dividend.Length)
{
dividing = int.Parse(dividend.Substring(currentInt,intNumberstoGet));
remainder *= 10;
dividing += remainder;
}
}
}
}
return result;
}
Here you go. Another example. It's 10 to 30 times faster than the accepted answer.
static string AddNumStr(string v1, string v2)
{
var v1Len = v1.Length;
var v2Len = v2.Length;
var count = Math.Max(v1Len, v2Len);
var answ = new char[count + 1];
while (count >= 0) answ[count--] = (char)((v1Len > 0 ? v1[--v1Len] & 0xF:0) + (v2Len>0 ? v2[--v2Len]&0xF : 0));
for (var i = answ.Length - 1; i >= 0; i--)
{
if (answ[i] > 9)
{
answ[i - 1]++;
answ[i] -= (char)10;
}
answ[i] = (char)(answ[i] | 48);
}
return new string(answ).TrimStart('0');
}
Below SO question has some interesting approaches. Though the answer is in Java, but you will surely get to know what needs to be done.
How to handle very large numbers in Java without using java.math.BigInteger
public static int[] addTwoNumbers(string s1, string s2)
{
char[] num1 = s1.ToCharArray();
char[] num2 = s2.ToCharArray();
int sum = 0;
int carry = 0;
int size = (s1.Length > s2.Length) ? s1.Length + 1 : s2.Length + 1;
int[] result = new int[size];
int index = size - 1;
int num1index = num1.Length - 1;
int num2index = num2.Length - 1;
while (true)
{
if (num1index >= 0 && num2index >= 0)
{
sum = (num1[num1index]-'0') + (num2[num2index]-'0') + carry;
}
else if(num1index< 0 && num2index >= 0)
{
sum = (num2[num2index]-'0') + carry;
}
else if (num1index >= 0 && num2index < 0)
{
sum = (num1[num1index]-'0') + carry;
}
else { break; }
carry = sum /10;
result[index] = sum % 10;
index--;
num1index--;
num2index--;
}
if(carry>0)
{
result[index] = carry;
}
return result;
}

Categories