String Format Returns Unexpected Results - c#

I have a simple class that contains a property Format which is set to any given format specifier. I then use the property of this class to, as the name suggest, format the string.
Take the following example:
public class FormatDefinition {
public string Format { get; set; }
}
class Program {
static void Main() {
var formatDefinition = new FormatDefinition {
Format = "N"
};
var number = 20.5;
var formatOne = string.Format("{0:" + formatDefinition.Format + "}", number);
var formatTwo = string.Format("{0:formatDefinition.Format}", number);
var formatThree = $"{number:formatDefinition.Format}";
Console.WriteLine(formatOne); // 20.5
Console.WriteLine(formatTwo); // formatDefinition21Format
Console.WriteLine(formatThree); // formatDefinition21Format
Console.ReadLine();
}
}
Can someone please explain why formatTwo and formatThree have a result of formatDefinition21Format? It seems the period . is replaced by the formatted number.

You are specifying a custom numeric format string consisting of the string "formatDefinition.Format".
This is taken to mean constant string "formatDefinition" followed by the decimal point (and therefore the entire number goes here) followed by constant string "Format".
The number is rounded to zero decimal places because there are no digits specified after the decimal point.
The string formatDefinition.Format is not interpreted as C# code.

According to the documentation for Custom Number Format Strings:
For fixed-point format strings (that is, format strings that do not
contain scientific notation format characters), numbers are rounded to
as many decimal places as there are digit placeholders to the right of
the decimal point.
It's because you have a decimal point with no digit placeholders to its right. You're telling it to round the number to zero decimal places - in other words, round to the nearest whole number.
These are all functionally the same - all return a22b.
string.Format("{0:a.b}", 21.5);
string.Format("{0:a0b}", 21.5);
string.Format("{0:a0.b}", 21.5);
Here's a DotNetFiddle.

Related

Converting Long String to Double in C#

I have the following code to convert a very long numeric string.
using System;
class MainClass {
public static void Main (string[] args) {
string longString = "1000000000000000000000000000001";
double convertedString = Double.Parse(test);
Console.WriteLine(test2);
}
}
However, convertedString is outputted in scientific notation:
1E+30
Is there a way to retain the exact value of the double when I convert it from a string?
The format of the output and the precision of the variable itself have nothing to do with each other. You can get the format you want by changing the format string, e.g.
Console.WriteLine("{0:N}", test1);
As for the precision of the variable, you should be aware that floating point numbers are not precise. And your number is about ten digits too long to fit into a long.
You will either need to store that number as a custom data type or, if it is just an identifier and not actually a number on which you need to perform math, simply store it as a string.

string format money , [duplicate]

I need to display a number with commas and a decimal point.
Eg:
Case 1 : Decimal number is 432324 (This does not have commas or decimal points).
Need to display it as: 432,324.00.
Not: 432,324
Case 2 : Decimal number is 2222222.22 (This does not have commas).
Need to display it as: 2,222,222.22
I tried ToString("#,##0.##"), but it is not formatting it correctly.
int number = 1234567890;
number.ToString("#,##0.00");
You will get the result 1,234,567,890.00.
Maybe you simply want the standard format string "N", as in
number.ToString("N")
It will use thousand separators, and a fixed number of fractional decimals. The symbol for thousands separators and the symbol for the decimal point depend on the format provider (typically CultureInfo) you use, as does the number of decimals (which will normally by 2, as you require).
If the format provider specifies a different number of decimals, and if you don't want to change the format provider, you can give the number of decimals after the N, as in .ToString("N2").
Edit: The sizes of the groups between the commas are governed by the
CultureInfo.CurrentCulture.NumberFormat.NumberGroupSizes
array, given that you don't specify a special format provider.
Try with
ToString("#,##0.00")
From MSDN
*The "0" custom format specifier serves as a zero-placeholder symbol. If the value that is being formatted has a digit in the position where the zero appears in the format string, that digit is copied to the result string; otherwise, a zero appears in the result string. The position of the leftmost zero before the decimal point and the rightmost zero after the decimal point determines the range of digits that are always present in the result string.
The "00" specifier 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 "00" would result in the value 35.*
I had the same problem. I wanted to format numbers like the "General" format in spreadsheets, meaning show decimals if they're significant, but chop them off if not. In other words:
1234.56 => 1,234.56
1234 => 1,234
It needs to support a maximum number of places after the decimal, but don't put trailing zeros or dots if not required, and of course, it needs to be culture friendly. I never really figured out a clean way to do it using String.Format alone, but a combination of String.Format and Regex.Replace with some culture help from NumberFormatInfo.CurrentInfo did the job (LinqPad C# Program).
string FormatNumber<T>(T number, int maxDecimals = 4) {
return Regex.Replace(String.Format("{0:n" + maxDecimals + "}", number),
#"[" + System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator + "]?0+$", "");
}
void Main(){
foreach (var test in new[] { 123, 1234, 1234.56, 123456.789, 1234.56789123 } )
Console.WriteLine(test + " = " + FormatNumber(test));
}
Produces:
123 = 123
1234 = 1,234
1234.56 = 1,234.56
123456.789 = 123,456.789
1234.56789123 = 1,234.5679
Try with
ToString("#,##0.###")
Produces:
1234.55678 => 1,234.556
1234 => 1,234
For Razor View:
$#string.Format("{0:#,0.00}",item.TotalAmount)
CultureInfo us = new CultureInfo("en-US");
TotalAmount.ToString("N", us)
Your question is not very clear but this should achieve what you are trying to do:
decimal numericValue = 3494309432324.00m;
string formatted = numericValue.ToString("#,##0.00");
Then formatted will contain: 3,494,309,432,324.00
All that is needed is "#,0.00", c# does the rest.
Num.ToString("#,0.00"")
The "#,0" formats the thousand separators
"0.00" forces two decimal points
If you are using string variables you can format the string directly using a : then specify the format (e.g. N0, P2, etc).
decimal Number = 2000.55512016465m;
$"{Number:N}" #Outputs 2,000.55512016465
You can also specify the number of decimal places to show by adding a number to the end like
$"{Number:N1}" #Outputs 2,000.5
$"{Number:N2}" #Outputs 2,000.55
$"{Number:N3}" #Outputs 2,000.555
$"{Number:N4}" #Outputs 2,000.5551
string Mynewcurrency = DisplayIndianCurrency("7743450.00");
private string DisplayIndianCurrency(string EXruppesformate)
{
string fare = EXruppesformate;
decimal parsed = decimal.Parse(fare, CultureInfo.InvariantCulture);
CultureInfo hindi = new CultureInfo("en-IN");
// string text = string.Format(hindi, "{0:c}", parsed);if you want <b>Rs 77,43,450.00</b>
string text = string.Format(hindi, "{0:N}", parsed); //if you want <b>77,43,450.00</b>
return ruppesformate = text;
}
For anyone looking at this now, and getting the "No overload for method 'ToString' takes 1 argument" when using:
TotalNumber.ToString("N")
My solution has been to use :
TotalNumber.Value.ToString("N")
I often get stuck on this when working directly inside an MVC View, the following wasn't working:
#Model.Sum(x => x.Number).ToString("N")
Whereas this works:
#Model.Sum(x => x.Number).Value.ToString("N")

Remove trailing zeros and thousand separator (comma)

Since I am using this to remove trailing zeros when there is no value behind decimal:
decimal.Parse(variable).ToString("G29")
But it doesn't give thousand separator. For example:
string amount = "54321.00"
string amount2 = "54321.55"
string parsed = decimal.Parse(amount).ToString("G29");
string parsed2 = decimal.Parse(amount2).ToString("G29");
//parsed = 54321
//parsed2 = 54321.55
//my goal
//parsed = 54,321
//parsed2 = 54,321.55
Is there any better format type?
Use a custom format
string format = "#,#.##";
decimal noDecimalPlaces = 54321.00m;
decimal decimalPlaces = 54321.55m;
Console.WriteLine(noDecimalPlaces.ToString(format)); // writes 54,321
Console.WriteLine(decimalPlaces.ToString(format)); // writes 54,321.55
You can read more about formatting decimals on msdn.
The way this works
The latter part .## specifies that you allow up to two decimal places. The former part #,# specifies that you want to separate the integer part of your value.
Note:
The number formatting is still culture specific, so for cultures that use , as the decimal separator and . for digit grouping your numbers will be displayed as 54.321 and 54.321,55 instead. You can find out more about formatting in .NET here.

How to use String.Format to format a number with comma separators and floating decimal point?

Suppose I have a list of decimal numbers that I must format with a comma every three places, plus the appropriate number of digits after the decimal point. I want to use the .net string.Format method.
I want it to work like this:
string format = ???;
string s1 = string.Format(format, "1500"); // "1,500"
string s2 = string.Format(format, "1500.25"); // "1,500.25"
string s3 = string.Format(format. "3.1415926358979"); // "3.1415926358979"
I have seen other answers where the digits after the decimal are either limited to a fixed number of digits or truncated entirely, but this doesn't work for my application. I want to add the comma-separator to the whole part of the number, but keep the digits after the decimal exactly as they are.
First problem, you need to parse your strings before you can format them. There maybe some lose of precision. Then you need to decide what your maximum amount of precision you need is. Then you can do something like this:
string format = "{0:#,##0.#############}";
string s1 = string.Format(format, double.Parse("1500")); // "1,500"
string s2 = string.Format(format, double.Parse("1500.25")); // "1,500.25"
string s3 = string.Format(format, double.Parse("3.1415926358979")); // "3.1415926358979"
The # after the decimal place is a place holder for a decimal digit. If there are no more digits it won't show trailing zeros.
If being limited to a number of decimal places or possibly losing precision when converting to double. You could do something really cludgy like this:
public static string DecimalFormatCludge(string original)
{
var split = original.Split('.');
return string.Join(".", (new [] { int.Parse(split[0]).ToString("#,##0")}).Concat(split.Skip(1)));
}
This will split on the . in the string, parse the first part as an int, convert it back to a string correctly formatted and then just stick the decimal part back on (if there is one)
something like this?
string s1 = format.ToString("#,##0.00");
The format is something like this:
string format = "{0:#,##.##################}";

Format decimal number with custom amount of digits after comma

I have this custom extension that should format a decimal number with a custom amount of digits after comma.
public static decimal FormatDecimal(this decimal value, int decimalSeparator = 2)
{
decimal returnValue = Math.Round(value, decimalSeparator, MidpointRounding.AwayFromZero);
return returnValue;
}
The problem is that doesn't work as expected.
If I do like this:
decimal number = 12345;
and then:
decimal formatedNumber = number.FormatDecimal(2);
the result should be:
12345.00
instead the result is:
12345
What I am doing wrong?
Here's the extension function working
public static string FormatDecimal(this decimal value, int decimalSeparator = 2)
{
return value.ToString(string.Format("0.{0}", new string('0', decimalSeparator)));
}
I think the right way is to using The "0" custom format specifier;
Replaces the zero with the corresponding digit if one is present;
otherwise, zero appears in the result string.
For example;
decimal d = 12345;
Console.WriteLine(d.ToString("#.00")); // 12345.00
You're probably looking to format the string representation of your decimal instead. Try this:
decimal myNumber = 12345.67m;
string formattedNumber = myNumber.ToString("N3");
Console.WriteLine(formattedNumber); // Prints "12345.670"
See here for more information: https://msdn.microsoft.com/en-us/library/dwhawy9k%28v=vs.110%29.aspx
From MSDN:
Standard numeric format strings are used to format common numeric types. A standard numeric format string takes the form Axx, where:
A is a single alphabetic character called the format specifier. Any numeric format string that contains more than one alphabetic character, including white space, is interpreted as a custom numeric format string. For more information, see Custom Numeric Format Strings.
xx is an optional integer called the precision specifier. The precision specifier ranges from 0 to 99 and affects the number of digits in the result. Note that the precision specifier controls the number of digits in the string representation of a number. It does not round the number itself. To perform a rounding operation, use the Math.Ceiling, Math.Floor, or Math.Round method.
When precision specifier controls the number of fractional digits in the result string, the result strings reflect numbers that are rounded away from zero (that is, using MidpointRounding.AwayFromZero).
You should specify the formatting when you display the string.
What you need is to do the following, when you convert to string:
String.Format("{0:0.00}", formatedNumber);
Refer to This article for more details:

Categories