可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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 ,
.
回答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:
Simple one line code :
public static string DoFormat(double myNumber)
{
return string.Format(\"{0:0.00}\", myNumber).Replace(\".00\",\"\");
}
回答8:
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;
}
回答9:
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\".
回答10:
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.##\"/>
回答11:
something like this will work too:
String.Format(\"{0:P}\", decimal.Parse(Resellers.Fee)).Replace(\".00\", \"\")
回答12:
String.Format(\"{0:0.00}\", Convert.ToDecimal(totalPrice))
回答13:
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]
回答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\"