I have a simple string received via a parameter:
"1.00"
Based on locale of visitor it sometimes converts to:
"1" or "1,00"
The second one is a problem, I always need it to be a period (dots). $,£
I am using:
decimal price = Convert.ToDecimal(stringPrice, new CultureInfo("en-GB"));
Why is it still converting to "1,00" decimal if I use en-GB culture? I tried InvariantCulture, and the same thing happens. Why is this happening? It shouldn't matter because it's on the back end, right?
The conversion is going fine - internally, you get a decimal representation of 1.00 in your variable (price). Whether you see "1,00" or something else depends on where you are outputting the variable. Please look at how you are printing it, to see how it should display.
Related
I have a problem I have not found any solution to:
I am getting data from a SAP system, which I receive as decimal. Sometimes I get values with one decimal place, ex. -18083195.1
My 3rd party front-end table framework needs it to be -18083195.10, because sometimes users want to copy the value between cells and the framework converts -18083195.1 to -180831951 in the copy event.
Without converting between decimal and string, I need to assert that the values always are in the the 0.00 decimal format, and of decimal type.
How can this be achieved?
You can check that the value is a decimal type using sample.GetType() == typeof(decimal).
Thanks for all your suggestions!
I found the error, and it was in my table-framework (Handsontable), where, of course, the values are converted to string and back. Due to the varying demands of the client, they wanted a specific format for percentage values, another for regular values, which confused the framework number format functionality. I found a way to work around that!
Thanks!
Fredrik
I've a double variable called totalCost and it's value is 1025.
The result of calling a simple string.Format is the following:
?string.Format("{0}",totalCost)
"1,025"
My thousand separator is the dot while the decimal separator is the coma.
The weird part is the following:
?string.Format("{0:0.0}",totalCost)
"1,0"
Doesn't it should be 1025.0 (or 1,025.0)?
It seems that it converts the double in a string (giving "1.025") and then re-parse it without using my separator settings (interpreting it as 1-and-25-thousandths) and finally it formats the converted value.
EDIT: the thread culture is:
?System.Threading.Thread.CurrentThread.CurrentCulture
{it-IT}
You scenario is not what you think it is. I am 100% sure that your real value of totalCost is actually 1.025 (one and twenty five thousandths), because this is the only value that will produce both the same results that you have given.
This can be seen with the following code:
double d = 1.025;
Console.WriteLine(string.Format(new System.Globalization.CultureInfo("it-IT"), "{0}",d));
//1,025
Console.WriteLine(string.Format(new System.Globalization.CultureInfo("it-IT"), "{0:0.0}",d));
//1,0
As you can see, both outputs match with yours. I would suggest you use a debugger to step through the code and see at which point the value is being changed. (perhaps you are dividing by 1000 somewhere along the line)
Direct Answer: There is no strange behaviour, the code is working exactly as expected.
today iv notice that all the place that im using decimal first thing is in the grid show comma instead of point
the second problame is when i edit or insert number with point it ignore the point
like i enterd "2.5" i got it as 25
thats like example code:
decimal a = Convert.ToDecimal("2.5");
the resoult of a is 25.
this problame is happening on the iis and also in my local machine.
it all over the place , how can i fix it ?
What culture are you currently on? This should do the work:
decimal a = Convert.ToDecimal("2.5", new CultureInfo("en-US"));
Also, for the comma showing:
string s = a.ToString(new CultureInfo("en-US"));
You can probably fix it by changing your default culture, or by forcing the use of a specific culture in the conversion calls (a).
Our wonderful, yet somehow slightly disturbing European cousins have gotten the decimal point and comma mixed up at some point in the past, so that thirty-five-thousand-and-seven-point-two-five is written as:
35.007,25
So what's almost certainly happening is that your culture settings are throwing away the thousands separator (regardless of where they are) so that "2.5" is 25. This means that a number like two-and-half-thousand (2,500) would almost certainly become two-and-a-half.
(a): In fact, you probably shouldn't force a specific culture in the conversion call, since the whole point of cultures is to adapt to people's needs. The Europeans thinks little enough of US bods already without giving them more reasons :-) What you're seeing is exactly what's supposed to be happening.
If you need a specific culture, configure your machine that way, and let your code use the default.
I have some float values I want to convert to a string, I want to keep the formatting the same when converting, i.e. 999.0000(float) -> 999.0000(String). My problem is when the values contain an arbitrary number of zeroes after the decimal point, as in the previous example, they are stripped away when converting to a string, so the result I actually end up with is 999.
I looked at the format specifiers for the toString() method on MSDN, the RoundTrip ('R') specifier looks like it will produce what I want, but it is only supported for Single, Double and BigInt variables. Is there a format specifier like this for float variables?? Or would it be easier to just convert the values to doubles?
UPDATE: Just for clarity, the reason why I want to keep the trailing zeroes is because I'm doing a comparison of decimal places, i.e. I'm comparing the number of digits after the decimal place between two values. So for example, 1.00 and 1.00000 have a different number of digits after the decimal point. I know it's a strange request, it's for work and the requirement is coming from on high.
UPDATE 2-3-11:
I was thinking about this too hard, I'm reading the numbers from a txt file and then parsing them as floats, I'm going to modify the program to check whether the string values are decimals or whole numbers. Sorry for wasting your time, although this was very insightful.
Use ToString() with this format:
12345.678901.ToString("0.0000"); // outputs 12345.6789
12345.0.ToString("0.0000"); // outputs 12345.0000
Put as much zero as necessary at the end of the format.
Firstly, as Etienne says, float in C# is Single. It is just the C# keyword for that data type.
So you can definitely do this:
float f = 13.5f;
string s = f.ToString("R");
Secondly, you have referred a couple of times to the number's "format"; numbers don't have formats, they only have values. Strings have formats. Which makes me wonder: what is this thing you have that has a format but is not a string? The closest thing I can think of would be decimal, which does maintain its own precision; however, calling simply decimal.ToString should have the effect you want in that case.
How about including some example code so we can see exactly what you're doing, and why it isn't achieving what you want?
You can pass a format string to the ToString method, like so:
ToString("N4"); // 4 decimal points Number
If you want to see more modifiers, take a look at MSDN - Standard Numeric Format Strings
In C#, float is an alias for System.Single (a bit like intis an alias for System.Int32).
One of the fun parts of multi-cultural programming is number formats.
Americans use 10,000.50
Germans use 10.000,50
French use 10 000,50
My first approach would be to take the string, parse it backwards until I encounter a separator and use this as my decimal separator. There is an obvious flaw with that: 10.000 would be interpreted as 10.
Another approach: if the string contains 2 different non-numeric characters, use the last one as the decimal separator and discard the others. If I only have one, check if it occurs more than once and discards it if it does. If it only appears once, check if it has 3 digits after it. If yes, discard it, otherwise, use it as decimal separator.
The obvious "best solution" would be to detect the User's culture or Browser, but that does not work if you have a Frenchman using an en-US Windows/Browser.
Does the .net Framework contain some mythical black magic floating point parser that is better than Double.(Try)Parse() in trying to auto-detect the number format?
I think the best you can do in this case is to take their input and then show them what you think they meant. If they disagree, show them the format you're expecting and get them to enter it again.
I don't know the ASP.NET side of the problem but .NET has a pretty powerful class: System.Globalization.CultureInfo. You can use the following code to parse a string containing a double value:
double d = double.Parse("100.20", CultureInfo.CurrentCulture);
// -- OR --
double d = double.Parse("100.20", CultureInfo.CurrentUICulture);
If ASP.NET somehow (i.e. using HTTP Request headers) passes current user's CultureInfo to either CultureInfo.CurrentCulture or CultureInfo.CurrentUICulture, these will work fine.
You can't please everyone. If I enter ten as 10.000, and someone enters ten thousand as 10.000, you cannot handle that without some knowledge of the culture of the input. Detect the culture somehow (browser, system setting - what is the use case? ASP? Internal app, or open to the world?), or provide an example of the expected formatting, and use the most lenient parser you can. Probably something like:
double d = Double.Parse("5,000.00", NumberStyles.Any, CultureInfo.InvariantCulture);
The difference between 12.345 in French and English is a factor of 1000. If you supply an expected range where max < 1000*min, you can easily guess.
Take for example the height of a person (including babies and children) in mm.
By using a range of 200-3000, an input of 1.800 or 1,800 can unambiguously be interpreted as 1 meter and 80 centimeters, whereas an input of 912.300 or 912,300 can unambiguously be interpreted as 91 centimeters and 2.3 millimeters.