Prevent double rounding in C# (and Blazor Server)? - c#

This is my first question here.
I have a number value with the data type double, which rounds the decimal number before it is set in the setter. In the input field of the number only 20 characters are allowed (without comma). This is checked in the function "CheckInput" and the boolean is returned. However, since the number is rounded after the decimal point, I am unable to check for the number of characters correctly. Does anyone have any idea how to prevent automatic rounding on the double?
This is my double Property:
[Required]
[StringLength(20, ErrorMessage = "Es sind max. 20 Zeichen erlaubt (ohne Komma).")]
private double _xValue;
public double XValue
{
get => _xValue;
set
{
var oldValue = value;
_xValue= value;
if (!CheckInput(InputField.XValue))
{
_xValue= oldValue;
}
}
}
This is the function to check my input number:
public bool CheckInput(InputField inputField)
{
if (inputField == InputField.XValue || inputField == InputField.YValue)
{
var xWertDecimal = Convert.ToDecimal(XValue);
var yWertDecimal = Convert.ToDecimal(YWert);
var valueString = String.Empty;
if (inputField == InputField.XValue) valueString = xWertDecimal.ToString();
else if (inputField == InputField.YValue) valueString = yWertDecimal.ToString();
var splittedString = valueString.Split(',');
if (splittedString.Length == 2)
{
if (splittedString[0].Length + splittedString[1].Length > 20)
{
Snackbar.Add("Max. 20 Zeichen erlaubt!");
return false;
}
}
else if (splittedString.Length == 1)
{
if (splittedString[0].Length > 20)
{
Snackbar.Add("Max. 20 Zeichen erlaubt!");
return false;
}
}
return true;
}
else if (inputField == InputField.Haeufigkeit)
{
if (Haeufigkeit <= 0)
{
Snackbar.Add("Häufigkeit muss größer als 0 sein!");
return false;
}
return true;
}
else
{
return true;
}
}

No need to convert the numbers to Decimal for getting the string value.
You can just use the ToString() method of the double itself, and check the amount of digits there.
Here is a solution that would return the number of the digits of the double:
public static int GetDigitAmount(double numberToCheck)
{
// For more info on conversion see: https://learn.microsoft.com/en-us/dotnet/api/system.double.tostring?view=net-6.0
var strValue = numberToCheck.ToString("G", System.Globalization.CultureInfo.InvariantCulture);
return strValue.Length - (strValue.Contains(".") ? 1 : 0);
}
And here's the quickly adjusted version of your code:
public bool CheckInput(InputField inputField)
{
if (inputField == InputField.XValue || inputField == InputField.YValue)
{
double? valueToCheck = null;
if (inputField == InputField.XValue) valueToCheck = XValue;
else if (inputField == InputField.YValue) valueToCheck = YWert;
if (valueToCheck != null && GetDigitAmount(valueToCheck.Value) > 20) {
Snackbar.Add("Max. 20 Zeichen erlaubt!");
return false;
}
return true;
}
else if (inputField == InputField.Haeufigkeit)
{
if (Haeufigkeit <= 0)
{
Snackbar.Add("Häufigkeit muss größer als 0 sein!");
return false;
}
return true;
}
else
{
return true;
}
}
public static int GetDigitAmount(double numberToCheck)
{
// For more info on conversion see: https://learn.microsoft.com/en-us/dotnet/api/system.double.tostring?view=net-6.0
var strValue = numberToCheck.ToString("G", System.Globalization.CultureInfo.InvariantCulture);
return strValue.Length - (strValue.Contains(".") ? 1 : 0);
}
P.S. I didn't have a chance to test it as it requires the other code that you have on your end. If there's any error, please let me know.

Related

Can't implicity convert type 'string' error

I updated my code this but I always get a '0' value for REQ_INSP_APPROVAL field regardless. When a name should be value of 1 for that field and it still shows as 0:
W_USER usr = new W_USER
{
Name = Convert.ToString(dgvMaster.CurrentRow.Cells [dgvMaster.CurrentCell.ColumnIndex].Value)
};
//WINS_USER usr = Convert.ToString(o);
//IQueryable<WINS_USER> users = dc.CMB_USERs;
showLegend = loadedReports.Where(f => f.form.EXEMPTFROMIP == 0 && f.form.FORMHEADER.INSPAPPROVALPROCESS == 1 && f.form.SUPERAPPROVED == 1 && usr.REQ_INSP_APPROVAL == 1).Count() > 0;I updated the code to this:
if (dgvMaster.CurrentRow == null)
return;
object o = dgvMaster.CurrentRow.Cells[dgvMaster.CurrentCell.ColumnIndex].Value;
// Error on the following line
W_USER usr = Convert.ToString(dgvMaster.CurrentRow.Cells[dgvMaster.CurrentCell.ColumnIndex].Value);
showLegend = loadedReports.Where(f => f.form.EXEMPTFROMIP == 0 &&
f.form.FORMHEADER.INSPAPPROVALPROCESS == 1 &&
f.form.SUPERAPPROVED == 1 &&
usr.REQ_INSP_APPROVAL == 1)
.Count() > 0;
Also in my designer class file I updated the REQ_INSP_APPROVAL from this
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_REQ_INSP_APPROVAL", DbType="Int")]
public System.Nullable<int> REQ_INSP_APPROVAL
{
get
{
return this._REQ_INSP_APPROVAL;
}
set
{
if ((this._REQ_INSP_APPROVAL != value))
{
this.OnREQ_INSP_APPROVALChanging(value);
this.SendPropertyChanging();
this._REQ_INSP_APPROVAL = value;
this.SendPropertyChanged("REQ_INSP_APPROVAL");
this.OnREQ_INSP_APPROVALChanged();
}
}
}
to
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_REQ_INSP_APPROVAL", DbType="Int")]
public int REQ_INSP_APPROVAL
{
get
{
return this._REQ_INSP_APPROVAL;
}
set
{
if ((this._REQ_INSP_APPROVAL != value))
{
this.OnREQ_INSP_APPROVALChanging(value);
this.SendPropertyChanging();
this._REQ_INSP_APPROVAL = value;
this.SendPropertyChanged("REQ_INSP_APPROVAL");
this.OnREQ_INSP_APPROVALChanged();
}
}
}
Before updating I was getting null for the REQ_INSP_APPROVAL now I'm getting as I stated '0'.
I know this is a lot but I really need help.
What is W_USER? Seems like W_USER is a class and you are trying to store a string value in the object of the class. That's why it is throwing you error. store below in a string variable.
W_USER usr=new W_USER(); usr.Name=Convert.ToString(dgvMaster.CurrentRow.Cells[dgvMaster.CurrentCell.ColumnIndex].Value);

how can i eliminate the error of "Use of unassigned local variable"

Hie i was programming c# and I am having issue getting error that use of unassigned variable where I have already declared the variable. Please help. I have even done building solution in visual studio 2010.
public decimal FinishCost
{
get {
decimal fnCost;
if (exteriorFinishChosen == ExteriorFinish.None)
{
fnCost = Finish.None;
}
else if (exteriorFinishChosen == ExteriorFinish.Standard)
{
fnCost = Finish.Standard;
}
else if (exteriorFinishChosen == ExteriorFinish.Pearlized)
{
fnCost = Finish.Pearlized;
}
else if (exteriorFinishChosen == ExteriorFinish.Custom)
{
fnCost = Finish.Custom;
}
return fnCost;
}
}
You need to give fnCost an initial value, even if that value is NULL or 0:
public decimal FinishCost
{
get
{
decimal fnCost = 0;
if (exteriorFinishChosen == ExteriorFinish.None)
{
fnCost = Finish.None;
}
else if (exteriorFinishChosen == ExteriorFinish.Standard)
{
fnCost = Finish.Standard;
}
else if (exteriorFinishChosen == ExteriorFinish.Pearlized)
{
fnCost = Finish.Pearlized;
}
else if (exteriorFinishChosen == ExteriorFinish.Custom)
{
fnCost = Finish.Custom;
}
return fnCost;
}
}

How to make a xaml textbox in silverlight accept only numbers with maximum one decimal point precision

How to make a xaml textbox in silverlight accept only numbers with maximum one decimal point precison. I have tried the answers in this question How to make a textBox accept only Numbers and just one decimal point in Windows 8. But it did not work. How can I do this ?
You can write a function like this,
txtDiscount.KeyDown += new KeyEventHandler(EnsureNumbers);
//Method to allow only numbers,
void EnsureNumbers(object sender, KeyEventArgs e)
{
if (e.Key == Key.Tab)
{
return;
}
bool result = EnsureDecimalPlaces();
if (result == false)
{
var thisKeyStr = "";
if (e.PlatformKeyCode == 190 || e.PlatformKeyCode == 110)
{
thisKeyStr = ".";
}
else
{
thisKeyStr = e.Key.ToString().Replace("D", "").Replace("NumPad", "");
}
var s = (sender as TextBox).Text + thisKeyStr;
var rStr = "^[0-9]+[.]?[0-9]*$";
var r = new Regex(rStr, RegexOptions.IgnoreCase);
e.Handled = !r.IsMatch(s);
}
else
{
e.Handled = true;
}
}
Method to ensure only 1 decimal,
bool EnsureDecimalPlaces()
{
string inText = txtDiscount.Text;
int decPointIndex = inText.IndexOf('.');
if (decPointIndex < 1 || decPointIndex == 1)
{
return false;
}
else
return true;
}

How i can extract year from datetime.now?

I want user to input the year of vehicle made but not more than this year. for example today is 2015, i don't want them to input 2020. but 2016 is ok.
here is my code.
property = validationContext.ObjectType.GetProperty("VehicleYear");
string vehicleYear = Convert.ToString(property.GetValue(validationContext.ObjectInstance, null));
if (!string.IsNullOrWhiteSpace(vehicleYear) && vehicleYear.Length == 4 && Convert.ToInt16(vehicleYear) >= 1980)
{
isVehicleOlderThan1981 = true;
}
else
{
isVehicleOlderThan1981 = false;
else if (value != null && Convert.ToDateTime(value) < DateTime.Now)
{
return new ValidationResult(this.ErrorMessage);
}
i only want to get a year from the DatetTime.now
Sorry i am new to the programming.
To get the year component of any date (including DateTime.Now), use this:
DateTime.Now.Year
I tried to clean your code for a bit and make it more logical (Also attached the answer you are looking for):
property = validationContext.ObjectType.GetProperty("VehicleYear");
var value = property.GetValue(validationContext.ObjectInstance, null);
int inputNumber;
//First check if input is number
if (!int.TryParse(value, out inputNumber))
{
this.ErrorMessage = "Input is not an integer!"
//you could also throw an exception here (depends on your error handling)
return new ValidationResult(this.ErrorMessage);
}
//retrieves the number of digits
int countDigits = Math.Floor(Math.Log10(year) + 1);
if (countDigits != 4)
{
this.ErrorMessage = String.Format("Input has {0} digits!",countDigits);
return new ValidationResult(this.ErrorMessage);
}
if (inputNumber > (DateTime.Now.Year + 1))
{
this.ErrorMessage = "Year is in the future!";
return new ValidationResult(this.ErrorMessage);
}
//inputNumber is now a valid year!
if(inputNumber > 1980)
{
isVehicleOlderThan1981 = true;
} else {
isVehicleOlderThan1981 = false;
}
Try this:
DateTime.Now.Year
You may also want to look at TryParse methods, it will simplify your code.
ie
int i;
if(int.TryParse("VehicleYear", out i)
{
//successful conversion, use int i for your comparisons etc.
}
else
{
//wasn't a valid year (can't be converted)
}
You need to use Year Year property from DateTime. Your else if may look like:
else if (value != null && Convert.ToDateTime(value).Year < DateTime.Now.Year)
NOTE: Convert.ToDateTime(value).Year will scream at you if value does not have correct date.
else if (value != null && Convert.ToDateTime(value) > DateTime.Now.AddYears(10))
{
//validation error
}

How to parse math expressions in C#? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Is there a string math evaluator in .NET?
Can C# parse mathematical expressions such as y=3*x + 3 into string? If so, ho?
I appreciate your help.
Here's a bit of code I wrote a while ago to parse infix (operator operand operator) equations.
There are some small classes and helper functions missing, but it should be fairly easy to implement them. If you need them or any help with it, let me know and I can upload them somewhere.
It's a basic implementation of Dijkstra's Shunting-yard algorithm
public Operand ExpressionTree
{
get;
private set;
}
private Stack<Operands.Operand> stack = new Stack<InfixParser.Operands.Operand>();
private Queue<Operands.Operand> outputQueue = new Queue<InfixParser.Operands.Operand>();
private void ParseFormulaString()
{
//Dijkstra's Shunting Yard Algorithm
Regex re = new Regex(#"([\+\-\*\(\)\^\/\ ])");
List<String> tokenList = re.Split(formulaString).Select(t => t.Trim()).Where(t => t != "").ToList();
for (int tokenNumber = 0; tokenNumber < tokenList.Count(); ++tokenNumber)
{
String token = tokenList[tokenNumber];
TokenClass tokenClass = GetTokenClass(token);
switch (tokenClass)
{
case TokenClass.Value:
outputQueue.Enqueue(new Value(token));
break;
case TokenClass.Function:
stack.Push(new Function(token, 1));
break;
case TokenClass.Operator:
if (token == "-" && (stack.Count == 0 || tokenList[tokenNumber - 1] == "("))
{
//Push unary operator 'Negative' to stack
stack.Push(new Negative());
break;
}
if (stack.Count > 0)
{
String stackTopToken = stack.Peek().Token;
if (GetTokenClass(stackTopToken) == TokenClass.Operator)
{
Associativity tokenAssociativity = GetOperatorAssociativity(token);
int tokenPrecedence = GetOperatorPrecedence(token);
int stackTopPrecedence = GetOperatorPrecedence(stackTopToken);
if (tokenAssociativity == Associativity.Left && tokenPrecedence <= stackTopPrecedence ||
tokenAssociativity == Associativity.Right && tokenPrecedence < stackTopPrecedence)
{
outputQueue.Enqueue(stack.Pop());
}
}
}
stack.Push(new BinaryOperator(token, Operator.OperatorNotation.Infix));
break;
case TokenClass.LeftParen:
stack.Push(new LeftParenthesis());
break;
case TokenClass.RightParen:
while (!(stack.Peek() is LeftParenthesis))
{
outputQueue.Enqueue(stack.Pop());
}
stack.Pop();
if (stack.Count > 0 && stack.Peek() is Function)
{
outputQueue.Enqueue(stack.Pop());
}
break;
}
if (tokenClass == TokenClass.Value || tokenClass == TokenClass.RightParen)
{
if (tokenNumber < tokenList.Count() - 1)
{
String nextToken = tokenList[tokenNumber + 1];
TokenClass nextTokenClass = GetTokenClass(nextToken);
if (nextTokenClass != TokenClass.Operator && nextTokenClass != TokenClass.RightParen)
{
tokenList.Insert(tokenNumber + 1, "*");
}
}
}
}
while (stack.Count > 0)
{
Operand operand = stack.Pop();
if (operand is LeftParenthesis || operand is RightParenthesis)
{
throw new ArgumentException("Mismatched parentheses");
}
outputQueue.Enqueue(operand);
}
String foo = String.Join(",", outputQueue.Select(t => t.Token).ToArray());
String bar = String.Join("", tokenList.ToArray());
Stack<Operand> expressionStack = new Stack<Operand>();
while (outputQueue.Count > 0)
{
Operand operand = outputQueue.Dequeue();
if (operand is Value)
{
expressionStack.Push(operand);
}
else
{
if (operand is BinaryOperator)
{
BinaryOperator op = (BinaryOperator)operand;
Operand rightOperand = expressionStack.Pop();
Operand leftOperand = expressionStack.Pop();
op.LeftOperand = leftOperand;
op.RightOperand = rightOperand;
}
else if (operand is UnaryOperator)
{
((UnaryOperator)operand).Operand = expressionStack.Pop();
}
else if (operand is Function)
{
Function function = (Function)operand;
for (int argNum = 0; argNum < function.NumArguments; ++argNum)
{
function.Arguments.Add(expressionStack.Pop());
}
}
expressionStack.Push(operand);
}
}
if (expressionStack.Count != 1)
{
throw new ArgumentException("Invalid formula");
}
ExpressionTree = expressionStack.Pop();
}
private TokenClass GetTokenClass(String token)
{
double tempValue;
if (double.TryParse(token, out tempValue) ||
token.Equals("R", StringComparison.CurrentCultureIgnoreCase) ||
token.Equals("S", StringComparison.CurrentCultureIgnoreCase))
{
return TokenClass.Value;
}
else if (token.Equals("sqrt", StringComparison.CurrentCultureIgnoreCase))
{
return TokenClass.Function;
}
else if (token == "(")
{
return TokenClass.LeftParen;
}
else if (token == ")")
{
return TokenClass.RightParen;
}
else if (binaryInfixOperators.Contains(token))
{
return TokenClass.Operator;
}
else
{
throw new ArgumentException("Invalid token");
}
}
private Associativity GetOperatorAssociativity(String token)
{
if (token == "^")
return Associativity.Right;
else
return Associativity.Left;
}
private int GetOperatorPrecedence(String token)
{
if (token == "+" || token == "-")
{
return 1;
}
else if (token == "*" || token == "/")
{
return 2;
}
else if (token == "^")
{
return 3;
}
else
{
throw new ArgumentException("Invalid token");
}
}
Possibly a duplicate of:
Is there a string math evaluator in .NET?
The short answer is no, for the long answer see the link. ( I recommend 'coppercoders' solution. )
Why don't you use Simple Math Parser or something is same?
link text
I took a cheap way out in a recent Silverlight application by scrubbing the string with a regex (for safety) and passing it to the JavaScript evaluator. It actually works very well but it's a hack I admit.
http://josheinstein.com/blog/index.php/2010/03/mathevalconverter

Categories