Why ADecimalNumber.ToString("#,##0") round the number? - c#

C#: I have a decimal number, I want to separate the thousand numbers by a comma but not round the number. As answers of stack overflow, I used .ToString("#,##0") but it rounds the number. It's not acceptable for me to round the number!
In my model I have:
public decimal? ADecimalNumber { get; set; }
In Controller I have:
ViewBag.ADecimalNumber = result?.ADecimalNumber;
And in View I have:
#(ViewBag.ADecimalNumber != null ? ViewBag.ADecimalNumber.ToString("#,##0") : '-')
The ViewBag value is 11106.8314M in quick-watch mode, and the ViewBag.ADecimalNumber.ToString("#,##0") result is "11,107".

It's default behavior of custom specifier. See The "#" Custom Specifier.
The "##" format string causes the value to be rounded to the nearest digit preceding the decimal, where rounding away from zero is always used. For example, formatting 34.5 with "##" would result in the value 35.

Rounding is part of the behavior of the # custom digit formatter. Use Math.Truncate() to cut off the digits after the period if you do not want rounding:
Math.Truncate(ViewBag.ADecimalNumber).ToString("#,##0")
If you want to print n decimal places though, multiply the number with the nth-power of 10, truncate, then divide by that same power, for example: Math.Truncate(123456.78M * 10M)/10M will give 123456.7 which you could print using the format string #,###.#

Related

Strange FormatException when converting to octal

So I have an integer number 208 I don't expect many to understand why I am doing this, but the end result of what I am trying to do is get the base-10 representation of octal number 208 (two-zero-eight). I expect that the confusing thing (for people that will try and answer this question) is that while 208 is an integer, I am using it more like a string containing the characters two, zero, and eight. Please let me know if there are any more questions on this, as I think it will cause some confusion.
Anyway, to get the base-10 representation of "208" here is what I do:
Convert int 208 into string "208".
Take the string "208", and parse from octal to decimal.
Then, here is the corresponding source code:
public byte OctalToDecimal(int octalDigits)
{
byte decimalValue = 0;
string octalString = string.Empty;
// first, get a string representation of the integer number
octalString = octalDigits.ToString();
// now, get the decimal value of the octal string
decimalValue = Convert.ToByte(octalString, 8);
// set the decimal-value as the label
return decimalValue;
}
I get a format exception when octalDigits = 208. I get a message about there being additional characters in the octalString's value. Why would that be? All I do is convert from int to string it's very short/simple, and not like I append anything on there. What is going on?
You should know that the digits for octal numbers are in the range 0 to 7
Here, some helpful links
the octal representations of bytes range from 000 to 377?
http://www.asciitable.com/
Octal numbers can not contain digit 8, like base-10 representation can't contain "digit" 10 and binary can't contain digit 2.

What is String Format C# {0,12:N0} (colon and commas) means?

Okay here's the code example:
string header = String.Format("{0,-12}{1,8}{2,12}{1,8}{2,12}{3,14}\n",
"City", "Year", "Population", "Change (%)");
Console.WriteLine(header);
string output;
foreach (var city in cities) {
output = String.Format("{0,-12}{1,8:yyyy}{2,12:N0}{3,8:yyyy}{4,12:N0}{5,14:P1}",
city.Item1, city.Item2, city.Item3, city.Item4, city.Item5,
(city.Item5 - city.Item3)/ (double)city.Item3);
Console.WriteLine(output);
}
}
}
// The example displays the following output:
// City Year Population Year Population Change (%)
//
// Los Angeles 1940 1,504,277 1950 1,970,358 31.0 %
// New York 1940 7,454,995 1950 7,891,957 5.9 %
// Chicago 1940 3,396,808 1950 3,620,962 6.6 %
// Detroit 1940 1,623,452 1950 1,849,568 13.9 %
i understand about the colon after the args {0:N0} means no decimal, but what about the comas? like {0,-12}, and {1,12} what does comma means after the argument of the string format?
MSDN Documentation is your friend (the link I gave in comments above wasn't the best either):
Composite Formatting
Each format item takes the following form and consists of the following components:
{index[,alignment][:formatString]}
So the index is obviously the index of the provided arguments:
String.Format("Second argument = {1}, first argument = {0}", arg1, arg2);
Alignment specifies the desired width of the field and horizontal alignment:
The formatted data in the field is right-aligned if alignment is positive and left-aligned if alignment is negative.
String.Format("{0,-12}" + // first argument, left align, 12 character wide column
"{1,8:yyyy}" + // second argument, right align, 8 character wide column,
// formatted as a year
"{2,12:N0}" + // third argument, right align, 12 character wide column,
// formatted as a number, 0 decimal places
And formatString you already know about (e.g. The Numeric ("N") Format Specifier).
They are index component and alignment component which is part of Composite Formatting. Here is composite formatting syntax;
{index[,alignment][:formatString]}
In your cases, {0,-12} and {1,12}, 0 and 1 are index component which is pointing your first 2 elements that you want to format. And -12 and 12 are alignment components. They can be negative or positive values.
Positive values indicate alignment to the right and negative values indicate alignment to the left.
If you wanna use alignment component, you have to separate it from the index component by a comma. Colon (:) separates alignment component with formatString as you can see on syntax.
Since you use {0,-12} for "Los Angeles" (which is 11 character), it will be aligned with one (12 - 11) white space character to the left.
Console.WriteLine("{0, -12}{1}", "Los Angeles", "1940"); // prints "Los Angeles 1940"
but Chicago (which is 7 character), it will be aligned five (12 - 7) white space character to the left as;
Console.WriteLine("{0, -12}{1}", "Chicago", "1940"); // prints "Chicago 1940"
For positive values;
Console.WriteLine("{0, 12}{1}", "Los Angeles", "1940"); // prints " Los Angeles1940"
but
Console.WriteLine("{0, 12}{1}", "Chicago", "1940"); // prints " Chicago1940"
The Numeric ("N") Format Specifier
The numeric ("N") format specifier converts a number to a string of
the form "-d,ddd,ddd.ddd…", where "-" indicates a negative number
symbol if required, "d" indicates a digit (0-9), "," indicates a group
separator, and "." indicates a decimal point symbol. The precision
specifier indicates the desired number of digits after the decimal
point. If the precision specifier is omitted, the number of decimal
places is defined by the current NumberFormatInfo.NumberDecimalDigits
property.
The result string is affected by the formatting information
of the current NumberFormatInfo object. The following table lists the
NumberFormatInfo properties that control the formatting of the result
string.
For N0 the actual output will no contains digits after the decimal point (like in integer values).
Align numbers with spaces
To align float number to the right use comma „,“ option before the
colon. Type comma followed by a number of spaces, e.g. „0,10:0.0“
(this can be used only in String.Format method, not in double.ToString
method). To align numbers to the left use negative number of spaces.

Show double as percentage without decimals with ToString method

Looking for:
95,4545454545455 -> 95 %
I tried using:
String resultAsPercentage = result.ToString("##0 %");
But, it shows
9545 %
Then, I solved my problem using regex:
Question: Why my ToString method hasn't worked? And how to fix it to avoid using regex?
Thanks in advance.
As documented on Custom Numeric Format Strings, the % modifier multiplies the value by 100 before inserting the %. It's intended to be used with fractions. To disable this special meaning of %, escape it by preceding it with #"\".
Alternatively, you could take the % out of the format string, and append it manually: result.ToString("##0") + " %".
If you don't care about rounding, you can use the following:
double result = 95.4545454545;
String resultAsPercentage = (int)result + " %";
System.out.println(resultAsPercentage);
Output is: 95 %
Casting to an int drops the decimal places without rounding
You can use thew P(ercentage) format specifier, you need to divide through 100 because the specifier multiplies it by 100:
decimal value = 95.4545454545455m;
String resultAsPercentage = (value / 100).ToString("P0"); // 95%
If you need the space between the value and the percentage symbol you could use this approach:
NumberFormatInfo nfi = (NumberFormatInfo)NumberFormatInfo.CurrentInfo.Clone();
nfi.PercentSymbol = " %";
String resultAsPercentage = (value / 100).ToString("P0", nfi); // 95 %
One way can be Clone a culture (like InvariantCulture), set it's PercentPositivePattern to 0, divide your value by 100 and get it's string representation using The percent ("P") format specifier with 0 precision and that cloned culture as;
var clone = (CultureInfo)CultureInfo.InvariantCulture.Clone();
clone.NumberFormat.PercentNegativePattern = 0;
Console.WriteLine(((int)95.4545454545455 / 100.0).ToString("P0", clone)); // 95 %
You can see all associated patterns on Remarks section on that page.
You can guaranteed to set PercentNegativePattern property as well for negative values.

Math.Round not keeping the trailing zero

I need all values to rounded to two decimal places. So 1.401 should round to 1.40, but Math.Round(value, 2) rounds to 1.4.
How can I force the trailing zero?
1.4 is the same as 1.40 - you just want to display it differently. Use a format string when calling ToString - like value.ToString("0.00")
1.4 == 1.40 the only time you'd ever need a trailing 0 is when you display the number..i.e. format it to string.
.ToString("N2");
The trailing zero is more of a formatting than a value issue, so use
foo.ToString("0.00")
I know this is an old question, but might help someone!
I am using a c# xml class to populate and then serialise to xml. One of the values is a double. If I assign a '7' to the value this gets serialised to '7' when I actually need '7.00'. Easiest way round this was just to do:
foo = doubleValue + 0.00M
And that makes the value 7.00 instead of just 7. Thought this was better then doing a ToString and then parsing it back.
The trailing zero is just a presentation. Math-wise, 1.40 and 1.4 are equivalent.
Use formatting instead to present it with the 2 decimal places:
String.Format("{0:0.00}", 1.4);
or
yourNumber.ToString("0.00");
It has to do with whether you use a decimal or a double.
While internally (as it appears from the Source Code) Math.Round() preserves the trailing zeros even on a double, still the fact that it is saved as a double in memory causes automatically to remove all trailing zeros
So if you do want tailing zeros, you can either use the string display functions to format it as others have answered, or make sure to pass in the original value as a decimal (causing to use internally Decimal.Math.Round which will deal only with decimals), and make sure to not cast the result to a double and also not to save it in a double variable.
Similarly if you have a decimal and you don't want trailing zeros, just cast it to a double (you can either cast the input to Math.Round or the result, it doesn't matter as long as somewhere in the way it is becoming a double).
It is a number (double?), so it doesn't have a trailing zero - you have to make it text and force a trailing zero.
You can use this function instead of round and just use it like you use round function.
import decimal
def printf(x, n):
d = decimal.Decimal(str(x))
d0 = -(d.as_tuple().exponent)
if d0 < n:
print("x = ", x)
else:
d1 = decimal.Decimal(str(round(x, n)))
d2 = d1.as_tuple().exponent
MAX = n + d2
if MAX == 0:
print("x = ", round(x, n))
else:
i = 0
print("x = ", round(x, n), end = '')
while i != MAX:
if i == (MAX - 1):
print("0")
else:
print("0", end = '')
i = i + 1
So you must have something like this.
>>> printf(0.500000000000001, 13)
>>> 0.5000000000000

Problem with C# double format

I am using next code to format double value:
String.Format("${0:0,0.#}",...);
It working great, but when numbers are less than 10, I got problem. Numbers are displayed as $03, $06 for example.
Please advise me correct string to have a double number in next format ddd,ddd,ddd,ddd.dd
Try this instead:
string result = string.Format("${0:#,##0.00}", d);
If your double represents a currency you should use:
string result = string.Format(CultureInfo.GetCultureInfo("en-US"), "{0:c}", d);
Note that if you omit the CultureInfo.InvariantCulture it could display using something other than $ on some computers. For example on my computer string.Format("{0:c}", d) gives 2,00 kr which might not be what you wanted.
In your example you don't actually need to use string.Format at all. You could use this instead:
string s = d.ToString("c", CultureInfo.GetCultureInfo("en-US"));
As well as being clearer and more concise, it also has the advantage of avoiding boxing. Of course if your format string is more complex than in your example then it would make sense to use string.Format.
And as a final remark I'd recommend against using doubles to store currency. A decimal type is probably more appropriate.
Use currency formatting:
String.Format("{0:C}", money);
String.Format("{0:C}", myDecimal);
or
myDecimal.ToString("C");
will display to two decimal places, include the comma separator and include the dollar sign (based on culture settings) in one fell swoop. If you want it to go to 1 or more than 2 decimal places, include a number after the C (i.e. C3)
Digits after decimal point
// just two decimal places
String.Format("{0:0.00}", 123.4567); // "123.46"
String.Format("{0:0.00}", 123.4); // "123.40"
String.Format("{0:0.00}", 123.0); // "123.00"
// max. two decimal places
String.Format("{0:0.##}", 123.4567); // "123.46"
String.Format("{0:0.##}", 123.4); // "123.4"
String.Format("{0:0.##}", 123.0); // "123"
// at least two digits before decimal point
String.Format("{0:00.0}", 123.4567); // "123.5"
String.Format("{0:00.0}", 23.4567); // "23.5"
String.Format("{0:00.0}", 3.4567); // "03.5"
String.Format("{0:00.0}", -3.4567); // "-03.5"
Thousands separator
String.Format("{0:0,0.0}", 12345.67); // "12,345.7"
String.Format("{0:0,0}", 12345.67); // "12,346"
Zero
Following code shows how can be formatted a zero (of double type).
String.Format("{0:0.0}", 0.0); // "0.0"
String.Format("{0:0.#}", 0.0); // "0"
String.Format("{0:#.0}", 0.0); // ".0"
String.Format("{0:#.#}", 0.0); // ""
Align numbers with spaces
String.Format("{0,10:0.0}", 123.4567); // " 123.5"
String.Format("{0,-10:0.0}", 123.4567); // "123.5 "
String.Format("{0,10:0.0}", -123.4567); // " -123.5"
String.Format("{0,-10:0.0}", -123.4567); // "-123.5 "
Custom formatting for negative numbers and zero
String.Format("{0:0.00;minus 0.00;zero}", 123.4567); // "123.46"
String.Format("{0:0.00;minus 0.00;zero}", -123.4567); // "minus 123.46"
String.Format("{0:0.00;minus 0.00;zero}", 0.0); // "zero"
Some funny examples
String.Format("{0:my number is 0.0}", 12.3); // "my number is 12.3"
String.Format("{0:0aaa.bbb0}", 12.3); // "12aaa.bbb3"
String.Format("${0:#,0.#}",...);
should do it.
See Custom Numeric Format Strings

Categories

Resources