I created a GUI which inputs a value number into another program and stores them in tags. I have a weird conversion problem. When I input 8.5 I get back a string 8.500000000000000... so I use the TryParse and the Double.ToString() method to get around this issue. But the bizarre part is that when I try with 6.9 the string becomes 6.9000000005367431600000.I use 2 dll which might be the cause of this problem. I've read this Decimals explanation but I don't understand how this can be fix my problem. How to get around with this conversion issue?
My Conversion method
private bool TryWrite()
{
// Read() returns a string(which represents int,double, float or string) read from another application
string Oldcopy = _inTouchWrapper.Read(tagNameBox.Text);
// Write() Write my input number into the application stored in a specific tag
_inTouchWrapper.Write(tagNameBox.Text, ValueBox.Text);
//OldCopy is to input back the old copy is the Write (new copy) cannot be performed
string newCopy = _inTouchWrapper.Read(tagNameBox.Text);
if (ValueBox.Text == Double.Parse(newCopy).ToString())
{
return true;
}
else
{
_inTouchWrapper.Write(tagNameBox.Text, Oldcopy);
return false;
}
}
More explanation about the software/and my code. The software has tags ex: Alarm1, TimeString...
Each tag has a type (int, real(a float), string) and a value. This value depends on the type. I cannot input 5.6 if the tag type is int. So I created this method which verifies is the input value can indeed be added in the software. How it works: I input a value in the software, read it back and if the added value matches with the read value, I indeed input it. Else, I input back the oldCopy.
It seems that string "6.9" is not directly converted to double. If is first converted to float and then casted to double. Here is an example:
var f = float.Parse("6.9");
var d = (double)f;
System.Diagnostics.Debug.WriteLine(d.ToString()); //6.90000009536743
PS: Why you not have the same issue with '8.5' is that it can exactly be represented in binary form.
Related
I'm writing a test for a webpage and I'm replacing some values from the recorded steps with csv values.
The problem is in the record I got this value:
public string UITboxNDocEditText = "866700228007551009280449220150921009003761527571";
and in the csv I got this value:
866700000007551009280449220150921009000001527571
the line I'm using to replace the value is this one:
this.UIMap.InsBDFParams.UITboxNDocEditText = TestContext.DataRow["n_b"].ToString();
the problem is that the script is instead writing this value : 8,66700000007551E+47
I tried casting the TestContext.DataRow line to a string instead of using the .ToString() method like this : (string)TestContext.DataRow["n_b"]; but got an error complaining about casting from a double so I assume the script is considering my value to be a double.
Any tips ?
You can use a format specifier to format the string, F0, the 0 stands for zero decimal places:
this.UIMap.InsBDFParams.UITboxNDocEditText =
((double)TestContext.DataRow["n_b"])
.ToString("F0");
Found out that encapsulating 866700000007551009280449220150921009000001527571 with double quotes solved the issue :
"866700000007551009280449220150921009000001527571".
I think it treats it as a string so it doesn't mess up the numbers.
I am getting the error "System.FormatException : input string was not correct".
TextBox2.Text = objnm.rupees(Convert.ToInt64(Convert.ToDecimal(txtWOrds.Text.Trim())));
First, you don't need to convert it to decimal (Convert.ToDecimal) and then to Int64 (Convert.ToIn64).
Second, if txtWOrds.Text is not a number or is empty, than you will get this exception. Make sure that it is a number.
Third, if your value is a number, than your problem likes somewhere in objnm.rupees()
You should check the input in case its empty, like string.IsNullOrEmpty(txtWOrds.Text) then proceed with the parsing of the contents of the textbox.
Also you should be using TryParse which evaluates if the text can be parsed and if true you can use the value of the out parameter of this method.
In your case it could fail if the TextBox is empty.
Also if its anything related to money/currency not sure if you need the conversion to Long (seems like a mismatch there, please clarify. If you want a specific set of decimal points then it would be better to use decimal.Round )
Decimal value = default(decimal);
bool isValid = decimal.TryParse(txtWOrds.Text.Trim(), out value);
if (isValid)
{
//your code using output 'value'
}
Remove Convert.Int64 and just use Convert.ToDecimal (ideally you should use decimal.TryParse). Also, ensure that the input textbox contains the correct type (a decimal)
I can't get my application to convert a string into a float:
float number = float.Parse(match);
Where match is "0.791794".
Why doesn't this work? The error I get is "Input string was not in a correct format.", but I can't understand what's wrong with it.
Try passing a culture object (i.e. InvariantCulture, if this is system-stored data and the format won't ever be different) to the overload that accepts one; your current culture may be set to something that expects a comma as the separator instead of a period (or similar).
You could also try
string x = (0.791794f).ToString()
just to see what it prints out.
Checking CultureInfo.CurrentCulture might be instructive as well.
(Also, sanity check -- I assume those quotes are from you, and not part of the string value themselves?)
Are you sure match is a string type? You may need to typecast it.
Seems to work fine in 2008
static void Main(string[] args)
{
var match = "0.791794";
float number = float.Parse(match);
Console.Out.Write(number);
}
You migth try restarting vs.
Hope that helps
I found a workaround for this error, but am now really curious as to why this would be happening, was wondering if anyone else has had this error.
My function is as follows:
public void Blog_GetRating(int blogID, ref decimal rating, ref int voteCount)
{
// Sql statements
// Sql commands
if (DataReader.Read())
{
// this line throws a 'Input string was not in a correct format.' error.
rating = decimal.Parse(DataReader["Rating"].ToString());
// this works absolutly fine?!
decimal _rating = 0;
decimal.TryParse(DataReader["Rating"].ToString(), out _rating);
rating = _rating;
}
}
Anyone ever seen that before?
What's even weirder is if i type this:
rating = decimal.Parse("4.0");
that works fine, the 4.0 is what is coming out from my DataReader.
As I said previous, the TryParse method works fine so it's not stopping me from carrying, but now I'm really interested to see if anyone has an answer for it.
Looking forward to some replies!
Sean
EDIT - SOLVED
The decimal.Parse method was working fine, the second time the function was running (was in a loop), a post hadn't been rated so a null value was being returned by the data reader. Wrapping COALESCE round my calculation in SQL solved the problem fine. Hence why, as you said, the tryparse method wasn't throwing an exception, just keeping the default of 0 to _rating.
That doesn't look weird to me at all.
Decimal.Parse() is supposed to throw an exception for bad formats. Decimal.TryParse() will not throw that exception, but instead just return false. The kicker is that you're not checking the return value from Decimal.TryParse(). I'll give you real good odds that Decimal.TryParse() returns false for every input that causes an exception with Decimal.Parse(), and true everywhere else. And when Decimal.TryParse() returns false, the output argument is always just "0".
The one possible caveat is localization. If Decimal.Parse() is complaining about a seemingly normal input, you might check if the number format (current culture) used on your server uses a comma rather than a decimal to separate the coefficient from the mantissa. But given your "4.0" test worked fine, I doubt this is the problem.
Finally, when doing this conversion from data reader you should consider the source column type of the data reader. If might already be a decimal. Why convert it to a string only to convert it back?
You are saying this:
// this works absolutly fine?!
decimal _rating = 0;
decimal.TryParse(DataReader["Rating"].ToString(), out _rating);
But you didn't actually check the return value of TryParse. I would guess that your TryParse is actually failing (returning false), since decimal.Parse and decimal.TryParse use the same "rules" for parsing, given the overloads you're using.
I suspect that neither is working as you think. Both are probably failing, but TryParse won't throw.
The sql decimal column won't parse to a string that can convert to a Decimal, so tryparse will return false. Try something like this:
if (Convert.IsDBNull(reader["DecimalColumn"]))
{
decimalData = 0m;
}
else
{
decimalData = reader.GetDecimal(reader.GetOrdinal("DecimalColumn"));
}
I am facing same problem today.
Try this:
rating = decimal.Parse("4,0");
It will give you same error.
The reason behind this is the culture. In the French culture, 4.0 is represented as 4,0, and hence it throws an Exception.
decimal.TryParse is culture invariant method and hence it works fine you.
Change your TryParse to this and try again:
if (!decimal.TryParse(DataReader["Rating"].ToString(), out _rating))
{
throw new Exception("Input string was not in a correct format");
}
I bet this does throw...
The problem is with the convert of the txt box value, but why?
string strChar = strTest.Substring(0, Convert.ToInt16(txtBoxValue.Text));
Error is: Input string was not in a correct format.
Thanks all.
txtBoxValue.Text probably does not contain a valid int16.
A good way to avoid that error is to use .tryParse (.net 2.0 and up)
int subLength;
if(!int.TryParse(txtBoxValue.Text,out subLength)
subLength= 0;
string strChar = strTest.Substring(0, subLength);
This way, if txtBoxValue.Textdoes not contain a valid number then subLength will be set to 0;
One thing you may want to try is using TryParse
Int16 myInt16;
if(Int16.TryParse(myString, out myInt16)
{
string strChar = strTest.Substring(0, myInt16);
}
else
{
MessageBox.Show("Hey this isn't an Int16!");
}
A couple reasons the code could be faulty.
To really nail it down, put your short conversion on a new line, like this:
short val = Convert.ToInt16(txtBoxValue.Text);
string strChar = strTest.Substring(0, val);
Likely the value in txtBoxValue.Text is not a short (it might be too big, or have alpha characters in it). If it is valid and val gets assigned, then strTest might not have enough characters in it for substring to work, although this normally returns a different error. Also, the second parameter of substring might require an int (not sure, can't test right now) so you may need to actually convert to int32 instead of 16.
What is the value of txtBoxValue.Text during your tests?
ASP.NET offers several validation controls for checking user input. You should use something like a CompareValidator or RegularExpressionValiditor in your WebForm if you're expecting a specific type of input, eg, an Integer.