How to best approach rounding up decimals in C# - c#

I've decimal value 18.8. Values that are stored in this variable can be of any kind. For example it can be 1.0000000 or 1.00004000 or 5.00000008.
I would like to write a method so that I can pass decimal to it and get rounded up string. This wouldn't be a problem if I would know decimal places I would like to get. But what I would like to get is:
When it's 1.0000000 it should return 1.
If it's 1.00004000 it should return 1.00004.
When it's 5.00000008 it should return 5.00000008.
So basically it should find all 0 that are behind last digit different then 0 and cut it off.
How should I approach it? What's the best method? I'm getting this value from SQL and put it in decimal variable but then i would like to display it and having 5.0000000 when it could be displayed as 5 is a bit overkill for me.
Hope I could get some nice suggestions.

AFAIK, ToString( "0.##" ) will do, just increase number of # so that your value won't round up. E.g.:
decimal d = 1.999m;
string dStr = d.ToString("0.###");
This will generate "1,999" string (delimiter depends upon used culture).
As a result, you can use common very long formatting string: "0.############################" - to format all your values.

So trim the zeroes from the end.
decimal d = 1.999m;
string dStr = d.ToString().TrimEnd('0').TrimEnd('.');

You can also use string.Format and here's the documentation of the different possible formats but I like Johan Sheehans cheat sheet more as a quick reference.
decimal number=4711.00004711m;
4711.00004711
string.Format("{0:0.#############}",number);
"4711,00004711"
number=42;
42
string.Format("{0:0.#############}",number);
"42"

Take a look at Jon Skeets article: http://www.yoda.arachsys.com/csharp/floatingpoint.html

Related

How can I get no more and no less than two decimal places in a decimal value?

With this code:
totalPriceCell.Value2 = TotalPrice;
...I was getting values such as "3.14963245" which I want to be "3.15" instead.
So I used this code:
totalPriceCell.Value2 = TotalPrice.ToString("#.##");
...and that did solve that problem, but I still get values such as "7.6" and "35" (which I want to be "7.60" and "35.00")
What can I do to accomplish this, outside of manually appending a "0" for vals such as "7.6" and manually appending ".00" for values such as "35"?
UPDATE
Niether suggestion worked, neither this:
totalPriceCell.Value2 = TotalPrice.ToString("F2");
...nor this:
totalPriceCell.Value2 = Math.Round(TotalPrice, 2).ToString("F2");
I still get "7.6" etc.:
UPDATE 2
It turns out to be an Excel problem, because when I added this:
MessageBox.Show(Math.Round(TotalPrice, 2).ToString("F2"));
...I did see values such as "7.60" (not "7.6").
It looks like you're trying to round the numbers to 2 decimal places, and then output the answer with trailing 0.
Just use the Math.Round() function to round, and then display using the .ToString("F2") format:
totalPriceCell.Value2 = Math.Round(TotalPrice, 2).ToString("F2");
Math.Round(arg1, arg2): Where 1st argument (arg1) is the value you want to round, and 2nd argument (arg2) is the decimal places you wish to round to.
.ToString("F2"): Usage of "F2" - F being the "fixed-point" format specified; 2 being the number of digits after the decimal point.
Hope this helps :)
You can use the #.00 format instead.
Because it's Excel, I had to tell the range/cell exactly how to behave, like so:
totalPriceCell.NumberFormat = "#,##0.00";

Rounding decimal number upto two decimal places

I am trying to round decimal number upto two decimal places which is working perfectly.
I am doing as below :
Math.Round(Amount, 2)
So, if I have Amount as 40000.4567, I am getting 40000.46which is exactly what I want.
Now problem is I have decimal number like 40000.0000, when I round it, the result is 40000, and what I really want is 40000.00. So round will always neglect trailing zeros.
To solve this problem, I have the option of converting it to string and use format , but I don't want to do that as that will be inefficient and I believe there must be some way to do it better.
I also tried something like
Decimal.Round(Amount, 2)
Now one way can be to check whether number contains anything in fractional part and use round function accordingly , but that is really bad way to do it.
I can't use truncate as well due to obvious reasons of this being related to amount.
What is the way around?
It is rounding correctly but you fail to understand that the value is not the format. There is no difference between the two values, 40000 and 40000.00, and you'll have a similar issue with something like 3.1.
Simply use formatting to output whatever number you have to two decimal places, such as with:
Console.WriteLine(String.Format("{0:0.00}", value));
or:
Console.WriteLine(value.ToString("0.00"));
You are mixing two things - rounding and output formatting. In order to output a number in a format you want you can use function string.Format with required format, for example:
decimal number = 1234.567m;
string.Format("{0:#.00}", number);
You can read more about custom numeric format strings in MSDN
I think what you're looking for is displaying two decimals, even if they are zero. You can use string.Format for this (I've also combined it with Round):
Console.WriteLine(string.Format("{0:0.00}", Math.Round(Amount, 2));
for rounding decimal number you can use
decimal number=200.5555m;
number= Math.Round(number, 2);
string numString= string.Format("{0:0.00}", number);

Convert.ToInt32 does not take the a zero ( 0 ) as a starting integer

I have a question or actually two regarding the
Convert.ToInt32 function or Int32.Parse.
It seems when I use Int32.Parse("06487965") or the other function it just seems to lose the 0.
So the output will be "6487965".
My questions:
Why is that exactly ?
How can I solve this without getting into crazy hacks ?
Leading-zeroes are purely a formatting idiom. An actual number has no leading zeroes as they make no sense and are superfluous.
You don't really have anything to solve, BUT, if you want to display the number at a later point with a leading zero, then you can use string formatting to achieve this.
int myNum = 6487965;
string formatted = string.Format("{0:00000000}", myNum);
Leading zeroes do not make sense mathematically
You can't have leading zeroes in an integer, if you must have leading zeroes best way is to keep your variable as string.
Because in that form, the leading 0, or 0s is/are nonsensical and redundant.
It can become useful in terms of formatting, for visual representation when you know how it should be formatted, but otherwise it is a non-issue.
Leading zeroes are meaningless when converting to a numeric type like Int32 - it only cares about the actual numeric value represented by the string you're converting from, which is the same regardless of the number of zeroes stuck on the front.
If later on in your program you want to convert your Int32 back to a string or output it to your user then at that point you need to do some formatting to get the number of leading zeroes you want. The MSDN article "How to: Pad a Number with Leading Zeros" would be a good place to start with that.
Leading 0's aren't represented when you ToString an int by default. You want to pass a format like "00000000".
int value = Int32.Parse("06487965");
string stringAgain = value.ToString("000000000");
integer 06487965 equals to integer 6487965
because, nobody uses pading, here is it:
int intValue = Int32.Parse("06487965");
string stringAgain = intValue.ToString().PadLeft(9, '0');

Float to String format specifier

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).

.NET's ToString() Number Truncating

So, WPF calls ToString() on objects when generating TextColumns in DataGrid and then i found out strange thing about ToString() method:
Check this out :
object a = 0.3780000001;//Something like this
Console.WriteLine(a.ToString());//Gets truncated in some cases
First, I thought it was just rounding, but few times I was able to reproduce such behavior on
doubles with < 15 digits after dot. Am I missing something?
To the computer, 0.378 and 0.378000...0001 are the same number. See this question: Why is floating point arithmetic in C# imprecise?
As defined on the MSDN page for System.Double, the double type only contains a maximum of fifteen digits of precision. Even though it maintains 17 internally, your figure contains 18 significant digits; this is outside the range of System.Double.
Use decimal instead of float for a more precise type.
By default, Double.ToString() truncates to 15 digits after the dot, but if you really want to use the double data type and you need those 2 extra digits, you can use th "G17" formatting string:
double x = 3.1415926535897932;
string pi = x.ToString("G17");
This will give you a string with the full 17 digits.
I wouldn't assume (so fast) that you found a bug in something as crucial as C#'s ToString implementation.
The behaviour you're experiencing is caused by the fact that a float is imprecisely stored in computer memory (also see this question).
maybe the number format's accuracy range doesn't contain that number? (ie, float only has accuracy to a few significant figures)
If you're data-binding the value, you can supply a ValueConverter which formats the number any way you want.
http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx
Set a to be an Decimal and it will print it correctly!
decimal a = 0.378000000000000001m;
Console.WriteLine(a.ToString());
You could have a common decimal format setting to use all the time.
eg
object a = 0.378000000000000001;
Console.WriteLine(a.ToString(Settings.DecimalFormat));

Categories