I'm converting an ancient VB6 program to C# and I came across some VB6 code that looked like this . . .
Format(part(PI).far_xdev, " #0.000;-#0.000")
at first I was confused about the two format fields separated by a semicolon. But it turns out that in VB6 this means that it uses the first one if the value of the number being formatted is 0 or positive, and the second if it's negative. If there were three formatting fields it would be positive, negative, and zero; four would be positive, negative, zero and null.
What's the equivalent of this in C# string formatting? How do I say "use this formating string for a positive number and that one for a negative number"?
(To whoever added the "This question may already have an answer": the problem with that link is that the linked question was asked in reference to some version of BASIC (based on the syntax) and did not explicitly say he was looking for an answer in C#, and neither of the two answers given specifically say they are in C#. We are left to surmise the languages involved based only on the tags. I think this new question and the resulting answers are much more clear, explicit and detailed)
Use the same separation by semi-column. Read more about that separator at msdn (supports up to three sections)
Console.WriteLine("{0:positive;negative;zero}", +1); //prints positive
Console.WriteLine("{0:positive;negative;zero}", -1); //prints negative
Console.WriteLine("{0:positive;negative;zero}", -0); //prints zero
You can use ToString on numeric value and pass format there
string formatted = 1.ToString("positive;negative;zero"); //will return "positive"
or use string.Format as shown in the comment section. But still you need to pass order position {0} to it.
string formatted = string.Format("{0:positive;negative;zero}", 1);
In order to check for null, you can use null coalescing operator (cast to object is required, since there is no implicit cast from int? to string). It becomes quite messy, so I would recommend to consider simple if statement.
int? v = null;
var formatted = string.Format("{0:positive;negative;zero}", (object) v ?? "null");
C# supports the same custom formatting:
string.Format("{0:#0.000;-#0.000}",part(PI).far_xdev);
Note that the format you use is the same as the standard fixed-point format with 3 significant digits:
string.Format("{0:F3}",part(PI).far_xdev);
Related
I'm very new to c# programming. I want to know how to add leading zeros for a integer type in c#.
ex:
int value = 23;
I want to use it like this ;
0023
Thanks in advance
You can't. There's no such contextual information in an int. An integer is just an integer.
If you're talking about formatting, you could use something like:
string formatted = value.ToString("0000");
... that will ensure there are at least 4 digits. (A format string of "D4" will have the same effect.) But you need to be very clear in your mind that this is only relevant in the string representation... it's not part of the integer value represented by value. Similarly, value has no notion of whether it's in decimal or hex - again, that's a property of how you format it.
(It's really important to understand this in reasonably simple cases like this, as it tends to make a lot more difference for things like date/time values, which again don't store any formatting information, and people often get confused.)
Note that there's one type which may surprise you: decimal. While it doesn't consider leading zeroes, it does have a notion of trailing zeroes (implicitly in the way it's stored), so 1.0m and 1.00m are distinguishable values.
Basically you want to add padding zeros.
string format specifier has a very simple method to this.
string valueAfterpadding;
int value = 23;
valueAfterpadding = value.ToString("D4");
Console.WriteLine(valueAfterpadding );
this solve your problem. just google it.
Integer wont accept leading zeros, it will only hold the real value of the integer.
The best we to have leading zeros is to convert it to string.
If you need a 4 digit value always, use the .ToString formatting to add leading 0's.
int value = 23;
var result = value.ToString("0000");
or if you want to have a leading 00 to any number, better append 00 to the string equivalent of the integer.
int value = 23;
var result = "00" + value.ToString();
This is not a programming issue. Numbers have no leading zeroes.
There are two things here that you can do:
If it is a number, then format it on the way out.
If it is something like a code (article number etc.) - those are NOT NUMBERS.
The second point is important. Things like social security numbers, part numbers etc. are strings - with only numeric characters allowed. You never add or subtract them and you must be prepared for format changes. They are not integers or any other number form to start with.
I have the following code:
float f = 0.02;
The results are equivalent to:
f = 0.0200
How to do this in C#?
A floating point number has a value (for example 0.02).
When you print it, you can format it into any number of different representations, including "0.002", "0.00200" and "scientific notation". It's the same value with the same precision - it's just printed differently (perhaps with a different number of digits after the decimal).
I believe your question is about "formatting":
String s = String.Format("{0:0.0000}", 0.002);
Here is much more detail:
http://msdn.microsoft.com/en-us/library/s8s7t687.aspx
http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx
http://www.dotnetperls.com/string-format
Under the hood, the number is still the same whether the trailing zeros are shown. You can't change what the number is, but you can change how it displays by using a .ToString() overide.
Specifically the Zero custom specifier.
This is so many times repeated at SO, but I would want to state my question explicitly.
How is a decimal which would look like 2.0100 "rightly" presented to the user as
another "decimal" 2.01?
I see a lot of questions on SO where the input is a string "2.0100" and need a decimal 2.01 out of it and questions where they need decimal 2.0100 to be represented as string "2.01". All this can be achieved by basic string.Trim, decimal.Parse etc. And these are some of the approaches followed:
decimal.Parse(2.0100.ToString("G29"))
Using # literal
Many string.Format options.
Various Regex options
My own one I used till now:
if (2.0100 == 0)
return 0;
decimal p = decimal.Parse(2.0100.ToString().TrimEnd('0'));
return p == 2.0100 ? p : 2.0100;
But I believe there has to be some correct way of doing it in .Net (at least 4) which deals with numeric operation and not string operation. I am asking for something that is not dealing with the decimal as string because I feel that ain't the right method to do this. I'm trying to learn something new. And would fancy my chances of seeing at least .1 seconds of performance gain since I'm pulling tens of thousands of decimal values from database :)
Question 2: If it aint present in .Net, which is the most efficient string method to get a presentable value for the decimal?
Edit: I do not just want a decimal to be presented it to users. In that case I can use it as a string. I do want it as decimal back. I will have to process on those decimal values later. So going by ToString approach, I first needs to convert it to string, and then again parse it to decimal. I am looking for something that doesn't deal with String class. Some option to convert decimal .20100 to decimal .201?
The "extra zeroes" that occur in a decimal value are there because the System.Decimal type stores those zeroes explicitly. For a System.Decimal, 1.23400 is a different value from 1.234, even though numerically they are equal:
The scaling factor also preserves any trailing zeroes in a Decimal number. Trailing zeroes do not affect the value of a Decimal number in arithmetic or comparison operations. However, trailing zeroes can be revealed by the ToString method if an appropriate format string is applied.
It's important to have the zeroes because many Decimal computations involve significant digits, which are a necessity of many scientific and high-precision calculations.
In your case, you don't care about them, but the appropriate answer is not "change Decimal for my particular application so that it doesn't store those zeroes". Instead, it's "present this value in a way that's meaningful to my users". And that's what decimal.ToString() is for.
The easiest way to format a decimal in a given format for the user is to use decimal.ToString()'s formatting options.
As for representing the value, 2.01 is equal to 2.0100. As long as you're within decimal's precision, it shouldn't matter how the value is stored in the system. You should only be worried with properly formatting the value for the user.
Numbers are numbers and strings are strings. The concept of "two-ness" represented as a string in the English language is 2. The concept of "two-ness" represented as a number is not really possibly to show because when you observe a number you see it as a string. But for the sake of argument it could be 2 or 2.0 or 02 or 02.0 or even 10/5. These are all representations of "two-ness".
Your database isn't actually returning 2.0100, something that you are inspecting that value with is converting it to a string and representing it that way for you. Whether a number has zeros at the end of it is merely a preference of string formatting, always.
Also, never call Decimal.parse() on a decimal, it doesn't make sense. If you want to convert a decimal literal to a string just call (2.0100).ToString().TrimEnd('0')
As noted, a decimal that internally stores 2.0100 could differ from one that stores 2.01, and the default behaviour of ToString() can be affected.
I recommend that you never make use of this.
Firstly, decimal.Parse("2.0100") == decimal.Parse("2.01") returns true. While their internal representations are different this is IMO unfortunate. When I'm using decimal with a value of 2.01 I want to be thinking:
2.01
Not:
struct decimal
{
private int flags;
private int hi;
private int lo;
private int mid;
/methods that make this actually useful/
}
While different means of storing 2.01 in the above structure might exist, 2.01 remains 2.01.
If you care about it being presented as 2.01 and not as 2.0 or 2.0100 then you care about a string representation. Your concern is about how a decimal is represented as a string, and that is how you should think about it at that stage. Consider the rule in question (minimum and maximum significant figures shown, and whether to include or exclude trailing zeros) and then code a ToString call appropriate.
And do this close to where the string is used.
When you care about 2.01, then deal with it as a decimal, and consider any code where the difference between 2.01 and 2.0100 matters to be a bug, and fix it.
Have a clear split in your code between where you are using strings, and where you are using decimals.
Ok, so I'm answering for myself, I got a solution.
return d / 1.00000000000000000000000000000m
That just does it. I did some benchmarking as well (time presented as comments are mode, not mean):
Method:
internal static double Calculate(Action act)
{
Stopwatch sw = new Stopwatch();
sw.Start();
act();
sw.Stop();
return sw.Elapsed.TotalSeconds;
}
Candidates:
return decimal.Parse(string.Format("{0:0.#############################}", d));
//0.02ms
return decimal.Parse(d.ToString("0.#############################"));
//0.014ms
if (d == 0)
return 0;
decimal p = decimal.Parse(d.ToString().TrimEnd('0').TrimEnd('.'));
return p == d ? p : d;
//0.016ms
return decimal.Parse(d.ToString("G29"));
//0.012ms
return d / 1.00000000000000000000000000000m;
//0.007ms
Needless to cover regex options. I dont mean to say performance makes a lot of difference. I'm just pulling 5k to 20k rows at a time. But still it's nice to know a simpler and cleaner alternative to string approach exists.
If you liked the answer, pls redirect your votes to here or here or here.
When using double.Parse, it seems to like to string away any trailing (insignificant) zeros from the string that I'm converting. I would like double.Parse to keep to places after the decimal. For example, here is some code:
tobereturned.MouseSensitivty = double.Parse(String.Format("{0:#.##}", tempstring[1]));
Debug.WriteLine("Converted " + String.Format("{0:#.##}", tempstring[1]) + " to " + tobereturned.MouseSensitivty);
The Debugger then writes
Converted 4.00 to 4
So it seems like double.Parse is doing something fishy here.
P.S. MouseSensitivity is also of the type double, so I can't do any string operations on it.
Your question is meaningless. Doubles don't have "places after the decimal" in the first place. They don't store anything that looks remotely like a "decimal representation of a number" internally. In fact, they don't store anything internally that even looks like recognizable text.
It reports 4 because 4.00 is exactly equal to 4. It is displaying the number "exactly four with no fractional part" as text according to its default rules for converting numbers to text.
Please read this. Yes, it is long, and difficult, but it is simply not possible to use floating-point numeric types properly without a real understanding of this material - and it doesn't matter what language you're using, either.
The double data type is simply a number; it doesn't keep track of the string that was parsed to create the value. Its string representation only comes into play when .ToString() is called.
If you know you always want two places after the decimal you can right-fill with zeros.
it is not the job of the double type to keep track of your desired display format.
Double does not store redundant zeros. In your view or presentation layer, you might want to format it to show you want it to appear, e.g., String.Format("{0:#.##}", doubleVariable)
What is the difference in C# between Convert.ToDecimal(string) and Decimal.Parse(string)?
In what scenarios would you use one over the other?
What impact does it have on performance?
What other factors should I be taking into consideration when choosing between the two?
There is one important difference to keep in mind:
Convert.ToDecimal will return 0 if it is given a null string.
decimal.Parse will throw an ArgumentNullException if the string you want to parse is null.
From bytes.com:
The Convert class is designed to
convert a wide range of Types, so you
can convert more types to Decimal than
you can with Decimal.Parse, which can
only deal with String. On the other
hand Decimal.Parse allows you to
specify a NumberStyle.
Decimal and decimal are aliases and
are equal.
For Convert.ToDecimal(string),
Decimal.Parse is called internally.
Morten Wennevik [C# MVP]
Since Decimal.Parse is called internally by Convert.ToDecimal, if you have extreme performance requirements you might want to stick to Decimal.Parse, it will save a stack frame.
One factor that you might not have thought of is the Decimal.TryParse method. Both Convert.ToDecimal and Parse throw exceptions if they cannot convert the string to the proper decimal format. The TryParse method gives you a nice pattern for input validation.
decimal result;
if (decimal.TryParse("5.0", out result))
; // you have a valid decimal to do as you please, no exception.
else
; // uh-oh. error message time!
This pattern is very incredibly awesome for error-checking user input.
One common suggestion related to original topic - please use TryParse() as soon as you not really sure that input string parameter WILL be correct number format representation.
Major Difference between Convert.ToDecimal(string) and Decimal.Parse(string)
is that Convert handles Null whereas the other throws an exception
Note: It won't handle empty string.
Convert.ToDecimal apparently does not always return 0. In my linq statement
var query = from c in dc.DataContext.vw_WebOrders
select new CisStoreData()
{
Discount = Convert.ToDecimal(c.Discount)
};
Discount is still null after converting from a Decimal? that is null. However, outside a Linq statement, I do get a 0 for the same conversion. Frustrating and annoying.
Knowing that Convert.ToDecimal is the way to go in most cases because it handles NULL, it, however, does not handle empty string very well. So, the following function might help:
'object should be a string or a number
Function ConvertStringToDecimal(ByVal ValueToConvertToDecimal As Object) As Decimal
If String.IsNullOrEmpty(ValueToConvertToDecimal.ToString) = False Then
Return Convert.ToDecimal(ValueToConvertToDecimal)
Else
Return Convert.ToDecimal(0)
End If
End Function