I have a exponential number : 4.65661287307739E-10
When I round it off using JavaScript, it gets converted as 5. I use following code
var roundFormattedNumber = function (n) {
var val = parseFloat(n.replace(/[^0-9.]/g, '')).toFixed(0);
Ext.util.Format.thousandSeparator = ',';
Ext.util.Format.decimalSeparator = '.';
return Ext.util.Format.number(val, '0,000');
};
When I try to first parse this number into decimal using C# I get : 0.000000000465661287307739M
decimal amount;
decimal.TryParse("4.65661287307739E-10", NumberStyles.Any, CultureInfo.InvariantCulture, out amount);
If I round off this value using C# result would be different as compared to JavaScript result.
Why there is a difference? Which result it correct?
Please suggest.
Thank you
When I round it off using JavaScript, it gets converted as 5.
That's not JavaScript, that's your code. You're removing everything from the string that isn't a digit or a .:
var val = parseFloat(n.replace(/[^0-9.]/g, '')).toFixed(0);
// -------------------^^^^^^^^^^^^^^^^^^^^^^^^
...so you're turning
4.65661287307739E-10
into
4.6566128730773910
and then parsing that, which naturally gives you a completely different number from 4.65661287307739E-10. There's no need to do that, JavaScript's parseFloat can interpret E-notation.
Whereas in your C# code, you're actually providing the E-notation number to the TryParse function.
Why there is a difference?
Because in the one case you're removing really important information from the string before asking JavaScript to parse it.
Which result it correct?
The C# one (although I have no idea why there's an M at the end of it).
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'm trying to format some doubles properly so that they will display properly for my uses (I'm building a statement in Devexpress, so I'm working with a lot of numbers).
Here are the basic formatting rules I'd like to have happen:
1000.2 -> 1,000.20
1000 -> 1,000
1000.22 -> 1,000.22
Is this possible using string formatting in C#? I've tried the following, but not been able to achieve my goal:
#,#.## - gives me 1,000.2 for the first value
#,#.#0 - gives me 1,000.00 for the second value
#,#.00 - gives me 1,000.00 for the second value
EDIT: Some more information. DevExpress gives me the ability to use string formatting to set up the values after they've been bound to the report. We're doing it at report time (and not at calculation time in the behind the scenes code) because we use the Sum function within the tables that DevExpress offers us. The reason we do THAT is so that we can minimize calls to our database by doing one large pull of data, then using that table over and over again in the statement and filtering based on the restrictions within.
EDIT EDIT:
Based on the feedback I've receieved here in the comments, it's not possible to perform the formatting I'd like to do with only providing a string format; I would need to insert some code either when I provide the data to the report (and then remove any and all formatting from the report) and perform all summing functions at the code level (to ensure that the sum values have the expected decimal places), or I would need to accept .00 at the end of, for example, some amount of yen (100 JPY would never be represented as 100.00 JPY, as an example).
This is a bit of an esoteric case, but it's good to know!
You can use string formatting coupled to a simple if condition. To shorten it's use, you can also make it an Extension method. It can look like this :
public static string FormatConditionnaly(this double input)
{
return input % 1 == 0 ? input.ToString("#,0") : input.ToString("#,0.00");
}
Basically, if you number does not contain any decimals (the % 1 == 0 check), you format it without decimals. If it fails the check, you add the two zeroes.
It is used like that :
const double flatNumber = 1000;
string result1 = flatNumber.FormatConditionnaly(); //1,000
const double numberWithDecimals = 1000.5;
string result2 = numberWithDecimals.FormatConditionnaly(); //1,000,50
Bit of a hack but you can give this a try:
s = String.Format("{0:N2}", 1000).Replace(".00", "");
Use the "N" format specifier as the format string when you call ToString(); See here
For example:
int intValue = 123456789;
Console.WriteLine(intValue.ToString("N2",
CultureInfo.InvariantCulture).Replace(".00", "");
You can customize group sizes etc. as needed.
Why don't you format the values before binding to DevExpress control using plain old C# (Assuming you are doing a bind, as you have not given sufficient details.)
In c# the Math.Round() should do the trick.
Example Math.Round(doubleValue,2) where the second parameter is the number of decimal places.
EDIT:
#,##0.00
I Do not have DevExpress controls to test my solution but I did find http://documentation.devexpress.com/#windowsforms/CustomDocument1498 online (not sure if you see it already).
It seems you can use the Number or Currency masks.
Also take a look at the Zero Placeholder under the custom section. based on the description, '0' is filled where the user has not supplied a value.
example: 123.4 --> 123.40
If the string that you're trying to format is in an XRTableCell of an XtraReport instance, you can handle the BeforePrint event on that cell to format its text. This event is triggered anytime that the report is rendered. Call GetCurrentColumnValue to retrieve the value that you want to format, use any of the code methods from the previous answers that will work for you, and then set that cell's text with your formatted string. Using #dweeberly's answer:
private void OnBeforePrint(object sender, PrintEventArgs e)
{
object value = this.GetCurrentColumnValue("YourField");
if (value != null)
{
yourCell.Text = String.Format("{0:N2}", value.ToString()).Replace(".00", "");
}
}
Based on the feedback I've receieved here in the comments, it's not possible to perform the formatting I'd like to do with only providing a string format; I would need to insert some code either when I provide the data to the report (and then remove any and all formatting from the report) and perform all summing functions at the code level (to ensure that the sum values have the expected decimal places), or I would need to accept .00 at the end of, for example, some amount of yen (100 JPY would never be represented as 100.00 JPY, as an example).
This is a bit of an esoteric case, but it's good to know!
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.
I have to format a collection of doubles to 2 decimal places and display it in a console app by seperating it with a comma (,).
I have used the following:
var result = GetResults() //returns 1.234125, 3.56345, 6.43254
Console.WriteLine(string.Join(",",result)
However this does not format the values to 2 decimal places. I'm looking to display 1.23,3.56,6.43 to the console. Also the elements in "result" collection could range for a few 1000 doubles.So I'm looking for an optimized piece of code which will not involve any boxing and will take the least time to display itself to the console.
Thanks,
-Mike
String.Join(result.Select(d => d.ToString("0.00"))
Custom Numeric Format Strings
Console class effectively buffers all received data, so multiple Console.Write calls actually don't reduce permormance. Also you don't have to get all the text in one huge piece. So my answer is:
IEnumerable<double> result = new double[] { 1.1234, 2.2345, 3.3456 };
foreach (double item in result)
Console.Write ("{0},", item.ToString("0.00"));
Console.WriteLine ();
Explicit double.ToString call allows to avoid unnecessary boxing. But I suggest you to compare performance in both ways before using more complicated one.
Also note that in some cultures a comma is already used as fractional separator.
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.