WP8 - C# - Parsing string to decimal FormatException - c#

I am currently trying to parse a string, "277.968", to decimal, but I am getting a FormatException exception.
I have read that I need to perform the decimal parse this way:
string str = "277.968";
decimal.Parse(str, CultureInfo.InvariantCulture);
Still, I am getting the said exception.
What could I do?
EDIT: Fixed float to decimal

Printing the lenght of the string, it reported it being 80 chars long.
Right, well that's the problem then. Your string isn't "277.968" - it's "277.968\0\0\0\0\0\0(...)" - and that can't be parsed.
My guess is that you've read this from a TextReader of some kind, but ignored the return value of Read, which is the number of characters that have been read.
So for example, if your current code is effectively:
char[] risul = new char[80];
reader.Read(risul, 0, risul.Length);
decimal value = decimal.Parse(new string(risul), CultureInfo.InvariantCulture);
then you should instead have:
char[] risul = new char[80];
int charsRead = reader.Read(risul, 0, risul.Length);
decimal value = decimal.Parse(new string(risul, 0, charsRead),
CultureInfo.InvariantCulture);
... although that's still assuming that you're reading all of the appropriate data in a single call to Read, which isn't necessarily the case. You may well just want:
string data = reader.ReadToEnd();
decimal value = decimal.Parse(data, CultureInfo.InvariantCulture);

Related

Is there a different way to convert to hexadecimal?

I'm trying to write some information to a special device that requires me to encode the string and I quote " an even number of bytes to write (1-32, base 10) "
The example string provided "DE AD BE EF CA FE" (works).
I have converted my string to decimal and from decimal to hexadecimal.
string TextToConvert = "Test Andrei";
TextToConvert=ConvertStringToHex(TextToConvert, Encoding.UTF8);
List<char> Chars = TextToConvert.ToCharArray().ToList();
string CharValue = "";
string secondHexConvert = "";
foreach(char c in Chars)
{
CharValue+=Convert.ToInt32(c);
secondHexConvert+=Convert.ToString(c, 16)+" ";
}
string hexValue = String.Format("{0:X}", CharValue)+" ";
I have found on internet a tool that converts to hexadecimal that works. The problem is that I can't figure what type of encoding is that. The site is this: https://codebeautify.org/decimal-hex-converter
from decimal "841011151163265110100114101105" to hex = "a9d741e82c990000000000000"
To convert such a big integer to a hexadecimal string, use the aptly named BigInteger type:
var num = BigInteger.Parse("841011151163265110100114101105");
string hex = num.ToString("X");
Console.WriteLine(hex);
will output:
0A9D741E82C98FC6A137B75371
but here's a snag, the output you showed in your question is somewhat different, let me show it together with what the code above produces:
0A9D741E82C98FC6A137B75371
a9d741e82c990000000000000
As you can see, the numbers start the same but your example then ends up with lots of zeroes.
The only way I understand this could happen is that they're in fact not using a type that can hold that many significant digits, so you get a rounding error.
Many of the dynamic programming languages allows you to use floating point numbers and integers interchangeably, I guess this is what happened, a floating point type that can only hold 17-18 significant digits or some such was used, and you lost precision. .NET, however, doesn't have built-in support for converting floating point types to hexadecimal.
You can see that .NET produces the exact value by converting back:
Console.WriteLine(BigInteger.Parse(hex, System.Globalization.NumberStyles.HexNumber));
outputs:
841011151163265110100114101105
In other words, I'm not sure you can get the exact same results in .NET.
Corollary: Don't use that site for this kind of conversion!
You can use the following code to convert a string to hexadecimal:
public static string ConvertStringToHex(String input, System.Text.Encoding encoding)
{
Byte[] stringBytes = encoding.GetBytes(input);
StringBuilder sbBytes = new StringBuilder(stringBytes.Length * 2);
foreach (byte b in stringBytes)
{
sbBytes.AppendFormat("{0:X2}", b);
}
return sbBytes.ToString();
}
And you just call it using:
string testString = "11111111";
string hex = ConvertStringToHex(testString, System.Text.Encoding.Unicode);

Conversion error parsing number formatted with a comma as the number group separator

In mvc I have formatted a numeric value using a comma as the number group separator as is specified in the Indian numbering system:
PaymentReceived = String.Format(new CultureInfo("en-IN", true), "{0:n}", t.PaymentReceived)
Later, I need to parse the string back to a numeric value. Here the FieldValue is of type long, while the right side value is of type string. How do I get the conversion to long?
I already have tried to do he following, but this is throwing an error message (the input string was not in correct format):
FieldValue = Convert.ToInt64( String.Format(new CultureInfo("en-IN", true), "{0:n}", t1.FieldValue))
As pointed out in the comment, you do not need to format a string with commas to convert it to a long. The commas are purely a presentation issue and None of the primitive number data types(int, long, double...) will maintain them.
To convert the string to long, do this.
FieldValue = Convert.ToInt64(t1.FieldValue)
To display the value as a comma separated number, do this
string formattedString = FieldValue.ToString("N0")
Your problem is not with the number group separator in your string. Your problem is that, when you formatted your number, you used the "{0:n}" format but did not specify a precision. From the docs:
If the precision specifier is omitted, the number of decimal places is defined by the current NumberFormatInfo.NumberDecimalDigits property.
For "en-IN" the default number of digits is 2. Thus your number, despite being a long, is being formatted with decimal digits. I.e. if you do:
long val = 1111111011;
var s = String.Format(new CultureInfo("en-IN", true), "{0:n0}", val);
Console.WriteLine(s);
The result looks like 1,11,11,11,011.00.
Later, you try to parse the string back to a long -- which throws a FormatException. The string is in an invalid format for a long because it contains a decimal point while long can only have integer values.
To avoid this problem, you could:
Format the initial value without a decimal point by using a precision of zero:
String.Format(new CultureInfo("en-IN", true), "{0:n0}", t.PaymentReceived)
Parse to decimal and round:
(long)Math.Round(decimal.Parse(s, new CultureInfo("en-IN", t.PaymentReceived)));

ulong.Parse(string, NumberStyles) Exception C#

i been working on this "string to Binary" method for longer than usual and i have no idea where i m going wrong.
i have already searched the internet for solution but nothing seem to be working the way it supposed to do.
public static string hexToBin(string strValue)
{
byte[] hexThis = ASCIIEncoding.ASCII.GetBytes(strValue.ToString());
string thiI = ToHex(strValue);
ulong number = UInt64.Parse(*string*, System.Globalization.NumberStyles.HexNumber);
byte[] bytes = BitConverter.GetBytes(number);
string binaryString = string.Empty;
foreach (byte singleByte in bytes)
{
binaryString += Convert.ToString(singleByte, 2);
}
return binaryString;
}
ToHex(string) takes string and returns its hex representation.
but all i keep getting is "Input string was not in a correct format." at the ulong.Parse(string, NumberStyle); and no matter what are my inputs i keep getting the "FormatException" "Input string was not in a correct format." Error.
the inputs and its outputs
string: format exception - "Hello"
hex: format exception - "48 65 6C 6C 6F"
byte[]: format exception - { 72, 101, 108, 108, 111 }
i have also tried using the "Hello" string, but it threw me the same error.
would you please let me know what i m doing wrong in here?
i also have tried "Clean/build/rebuild" restart visual studio, but i keep getting the same format exception.
EDIT,, used UInt64.Parse() not ulong.Parse() and the used string is "Hello" w/o quotation.
EDIT #2,,
so i did this based on knittl suggestion and used the Convert.ToUInt64 instead of the parse, but still getting same error
ulong binary;
string binThis;
byte[] ByteThis;
binThis = "Hello";
ByteThis = ASCIIEncoding.ASCII.GetBytes(binThis);
binary = Convert.ToUInt64(ByteThis);
Console.WriteLine(binary);
the CurrentCulture is set to en-US and i m also using en-US keyboard
EDIT #3 - Solved
thanks to knittl
the solution is as follow:
string thestring = "example";
string[] finale = new string[thestring.Length];
foreach (var c in ByteThis)
{
for (int i = 0; i < ByteThis.Length; i++)
{
thestring = Convert.ToString(c, 2);
thestring = "0" + thestring;
if (thestring.Length == 9)
thestring.Remove(0, 1);
finale[i] = thestring;
Console.WriteLine(finale[i]);
}
}
the final for is to check on the solution.
this question aimed to get the binary representation of a given string.
Not totally clear, what your method should do (i.e. what format the input string is. Is it a bas10 number, or already a hexadecimal number?)
If it's a hexadecimal number, use ulong.Parse(inputStr, NumberStyles.HexNumber). If not, simply use ulong.Parse(inputStr). Note that NumberStyles.HexNumber does not allow the 0x prefix (Convert.ToUInt64(inputStr) does however).
Then, once you have your input string parsed to a number, simply use Convert.ToString(number, 2) to convert to base2. You will notice that there is no overload which takes an ulong and an int, but you can simply cast your number to a (signed) long, since the binary representation will be identical between the two (cf. two's complement). So, in effect Convert.ToString((long)number, 2).
No need for complicated loops and conversions to byte arrays.
Bonus answer.
If you are not too concerned with performance, you can even use a LINQ one-liner:
Encoding.ASCII.GetBytes(inputStr).Aggregate(
new StringBuilder(),
(sb, ch) => sb.Append(Convert.ToString(ch, 2).PadLeft(8, '0')),
sb => sb.ToString());

Converting hex to decimal

I have an array of strings that are in hex format, for example {"3d", "20", "5a"}.
What would be a good way of converting each element of this string to decimal format?
I've tried using GetBytes(), but that doesn't seem to work since it sees "3d" as two different characters because it doesn't know that it is in hex format.
GetBytes() works fine in a situation like below but not if characters are in hex.
What am I missing here?
string a = "T";
byte[] b = {10};
b = System.Text.UTF8Encoding.Default.GetBytes(a);
Use int.Parse with NumberStyles.HexNumber.
int decValue = int.Parse(hexValue,System.Globalization.NumberStyles.HexNumber);
Try that.
HexValue is the number in hex format and decValue is in decimal...

How can I add decimal places to a TimeSpan object's totalseconds?

I have a function which returns seconds since epoch:
public static string getEpochSeconds()
{
TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1));
var timestamp = t.TotalSeconds;
return timestamp.ToString();
}
It outputs, for example: 1373689200.79987 but for the purposes of my application, I need it to output one more decimal place digit - for example 1373689200.799873. How is this possible?
Thanks!
Try using
return String.Format("{0}", timestamp.TotalSeconds);
and then you can use the format string. See this MSDN article for formatting information.
Edit 1:
Thanks #MortenMertner for the correct format.
Try using:
return String.Format("{0:N6}", timestamp.TotalSeconds);
to force 6 decimal places.
Edit 2:
You can lookup custom numeric format strings and standard numeric format strings to work out the best way to do this.
One way is to use F instead of N (both of which are standard numeric format strings). N will comma delimit the thousands where F will not.
return String.Format("{0:F6}", timestamp.TotalSeconds);
Edit 3:
As #sa_ddam213 points out in his answer, the standard ToString() method has an overload that accepts a formatting parameter. MSDN documents it here for a Double and you can clearly see that it accepts a standard numeric format string or a custom numeric format string so #sa_daam213's answer works out quite well too and is very similar to your original code but instead of N6 use F6 like in my Edit 2 above.
you can use timestamp.ToString("0.000000")
if you need result without rounding value
return t.TotalSeconds.ToString("F0")+"." +t.ToString("ffffff");
You should be able to add N6 (6 decimal places) to your ToString()
Example:
public static string getEpochSeconds()
{
TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1));
var timestamp = t.TotalSeconds;
return timestamp.ToString("N6");
}
If the last digit is not significant you can use the ToString("N6") (just adds a 0 at the end in this case). But if you want the real last digit, due to some strange way of converting doubles to string by .NET you may need something like the following.
public static string getEpochSeconds()
{
TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1));
//t {15901.03:57:53.6052183} System.TimeSpan
var timestamp1 = t.TotalSeconds;
//timestamp1 1373860673.6052184 double
var tstring1 = timestamp1.ToString("N6");
//tstring1 "1,373,860,673.605220" string
var timestamp = (long)(t.TotalSeconds * 1000000);
//timestamp 1373860673605218 long
string tstring =timestamp.ToString();
//tstring "1373860673605218" string
tstring = tstring.Substring(0, tstring.Length - 6) + "." + tstring.Substring(tstring.Length - 6);
//tstring "1373860673.605218" string
return tstring;
}
I have added the outputs also as a comment. Hope this helps.

Categories