问题
I have got a price field to display which sometimes can be either 100 or 100.99 or 100.9, What I want is to display the price in 2 decimal places only if the decimals are entered for that price , for instance if its 100 so it should only show 100 not 100.00 and if the price is 100.2 it should display 100.20 similarly for 100.22 should be same . I googled and came across some examples but they didn\'t match exactly what i wanted :
// 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\"
回答1:
An inelegant way would be:
var my = DoFormat(123.0);
With DoFormat
being something like:
public static string DoFormat( double myNumber )
{
var s = string.Format("{0:0.00}", myNumber);
if ( s.EndsWith("00") )
{
return ((int)myNumber).ToString();
}
else
{
return s;
}
}
Not elegant but working for me in similar situations in some projects.
回答2:
Sorry for reactivating this question, but I didn't find the right answer here.
In formatting numbers you can use 0
as a mandatory place and #
as an optional place.
So:
// just 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"
You can also combine 0
with #
.
String.Format("{0:0.0#}", 123.4567) // "123.46"
String.Format("{0:0.0#}", 123.4) // "123.4"
String.Format("{0:0.0#}", 123.0) // "123.0"
For this formating method is always used CurrentCulture
. For some Cultures .
will be changed to ,
.
Answer to original question:
The simpliest solution comes from @Andrew (here). So I personally would use something like this:
var number = 123.46;
String.Format(number % 1 == 0 ? "{0:0}" : "{0:0.00}", number)
回答3:
This is a common formatting floating number use case.
Unfortunately, all of the built-in one-letter format strings (eg. F, G, N) won't achieve this directly.
For example, num.ToString("F2")
will always show 2 decimal places like 123.40
.
You'll have to use 0.##
pattern even it looks a little verbose.
A complete code example:
double a = 123.4567;
double b = 123.40;
double c = 123.00;
string sa = a.ToString("0.##"); // 123.46
string sb = b.ToString("0.##"); // 123.4
string sc = c.ToString("0.##"); // 123
回答4:
Old question but I wanted to add the simplest option in my opinion.
Without thousands separators:
value.ToString(value % 1 == 0 ? "F0" : "F2")
With thousands separators:
value.ToString(value % 1 == 0 ? "N0" : "N2")
The same but with String.Format:
String.Format(value % 1 == 0 ? "{0:F0}" : "{0:F2}", value) // Without thousands separators
String.Format(value % 1 == 0 ? "{0:N0}" : "{0:N2}", value) // With thousands separators
If you need it in many places, I would use this logic in an extension method:
public static string ToCoolString(this decimal value)
{
return value.ToString(value % 1 == 0 ? "N0" : "N2"); // Or F0/F2 ;)
}
回答5:
try
double myPrice = 123.0;
String.Format(((Math.Round(myPrice) == myPrice) ? "{0:0}" : "{0:0.00}"), myPrice);
回答6:
I don't know of anyway to put a condition in the format specifier, but you can write your own formatter:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
// all of these don't work
Console.WriteLine("{0:C}", 10);
Console.WriteLine("{0:00.0}", 10);
Console.WriteLine("{0:0}", 10);
Console.WriteLine("{0:0.00}", 10);
Console.WriteLine("{0:0}", 10.0);
Console.WriteLine("{0:0}", 10.1);
Console.WriteLine("{0:0.00}", 10.1);
// works
Console.WriteLine(String.Format(new MyFormatter(),"{0:custom}", 9));
Console.WriteLine(String.Format(new MyFormatter(),"{0:custom}", 9.1));
Console.ReadKey();
}
}
class MyFormatter : IFormatProvider, ICustomFormatter
{
public string Format(string format, object arg, IFormatProvider formatProvider)
{
switch (format.ToUpper())
{
case "CUSTOM":
if (arg is short || arg is int || arg is long)
return arg.ToString();
if (arg is Single || arg is Double)
return String.Format("{0:0.00}",arg);
break;
// Handle other
default:
try
{
return HandleOtherFormats(format, arg);
}
catch (FormatException e)
{
throw new FormatException(String.Format("The format of '{0}' is invalid.", format), e);
}
}
return arg.ToString(); // only as a last resort
}
private string HandleOtherFormats(string format, object arg)
{
if (arg is IFormattable)
return ((IFormattable)arg).ToString(format, CultureInfo.CurrentCulture);
if (arg != null)
return arg.ToString();
return String.Empty;
}
public object GetFormat(Type formatType)
{
if (formatType == typeof(ICustomFormatter))
return this;
return null;
}
}
}
回答7:
Here is an alternative to Uwe Keim's method, which would still maintain the same method call:
var example1 = MyCustomFormat(123.1); // Output: 123.10
var example2 = MyCustomFormat(123.95); // Output: 123.95
var example3 = MyCustomFormat(123); // Output: 123
With MyCustomFormat
being something like:
public static string MyCustomFormat( double myNumber )
{
var str (string.Format("{0:0.00}", myNumber))
return (str.EndsWith(".00") ? str.Substring(0, strLastIndexOf(".00")) : str;
}
回答8:
Simple one line code :
public static string DoFormat(double myNumber)
{
return string.Format("{0:0.00}", myNumber).Replace(".00","");
}
回答9:
If your program needs to run quickly, call value.ToString(formatString) for ~35% faster string formatting performance relative to $"{value:formatString}" and string.Format(formatString, value).
Data
Code
using System;
using System.Diagnostics;
public static class StringFormattingPerformance
{
public static void Main()
{
Console.WriteLine("C# String Formatting Performance");
Console.WriteLine("Milliseconds Per 1 Million Iterations - Best Of 5");
long stringInterpolationBestOf5 = Measure1MillionIterationsBestOf5(
(double randomDouble) =>
{
return $"{randomDouble:0.##}";
});
long stringDotFormatBestOf5 = Measure1MillionIterationsBestOf5(
(double randomDouble) =>
{
return string.Format("{0:0.##}", randomDouble);
});
long valueDotToStringBestOf5 = Measure1MillionIterationsBestOf5(
(double randomDouble) =>
{
return randomDouble.ToString("0.##");
});
Console.WriteLine(
$@" $""{{value:formatString}}"": {stringInterpolationBestOf5} ms
string.Format(formatString, value): {stringDotFormatBestOf5} ms
value.ToString(formatString): {valueDotToStringBestOf5} ms");
}
private static long Measure1MillionIterationsBestOf5(
Func<double, string> formatDoubleUpToTwoDecimalPlaces)
{
long elapsedMillisecondsBestOf5 = long.MaxValue;
for (int perfRunIndex = 0; perfRunIndex < 5; ++perfRunIndex)
{
var random = new Random();
var stopwatch = Stopwatch.StartNew();
for (int i = 0; i < 1000000; ++i)
{
double randomDouble = random.NextDouble();
formatDoubleUpToTwoDecimalPlaces(randomDouble);
}
stopwatch.Stop();
elapsedMillisecondsBestOf5 = Math.Min(
elapsedMillisecondsBestOf5, stopwatch.ElapsedMilliseconds);
}
return elapsedMillisecondsBestOf5;
}
}
Code Output
C# String Formatting Performance
Milliseconds Per 1 Million Iterations - Best Of 5
$"{value:formatString}": 419 ms
string.Format(formatString, value): 419 ms
value.ToString(formatString): 264 ms
References
Custom Numeric Format Strings [docs.microsoft.com]
Qt Charts BarChart Example [doc.qt.io]
回答10:
I am afraid there is no built-in format that will do this. You will have to use a different format depending on whether the value is a whole number or not. Or always format to 2 decimal places, and manipulate the string afterwards to remove any trailing ".00".
回答11:
If none of the other answers work for you, it may be because you are binding the ContentProperty
of a control in the OnLoad
function, which means this won't work:
private void UserControl_Load(object sender, RoutedEventArgs e)
{
Bind.SetBindingElement(labelName, String.Format("{0:0.00}", PropertyName), Label.ContentProperty)
}
The solution is simple: there is a ContentStringFormat
property in the xaml. So when you create the label do this:
//if you want the decimal places definite
<Label Content="0" Name="labelName" ContentStringFormat="0.00"/>
Or
//if you want the decimal places to be optional
<Label Content="0" Name="labelName" ContentStringFormat="0.##"/>
回答12:
something like this will work too:
String.Format("{0:P}", decimal.Parse(Resellers.Fee)).Replace(".00", "")
回答13:
Try:
String.Format("{0:0.00}", Convert.ToDecimal(totalPrice));
回答14:
To make the code more clear that Kahia wrote in (it is clear but gets tricky when you want to add more text to it)...try this simple solution.
if (Math.Round((decimal)user.CurrentPoints) == user.CurrentPoints)
ViewBag.MyCurrentPoints = String.Format("Your current Points: {0:0}",user.CurrentPoints);
else
ViewBag.MyCurrentPoints = String.Format("Your current Points: {0:0.0}",user.CurrentPoints);
I had to add the extra cast (decimal) to have Math.Round compare the two decimal variables.
回答15:
This worked for me!
String amount= "123.0000";
String.Format("{0:0.##}", amount); // "123.00"
来源:https://stackoverflow.com/questions/6951335/using-string-format-to-show-decimal-up-to-2-places-or-simple-integer