My requirements are as follows:
I have a double number. It can be positive as well as negative. I want to use String.Format() to format it.
The Output Number(positive(no sign)/negative(including sign)/zero) should be fixed width: 11
All numbers should have 2 places of decimal.
Examples:
1.2 00000001.20
.2 00000000.20
-.2 -0000000.20
12 00000012.00
0 00000000.00
-0 00000000.00
12.555 00000012.55
Basically, what I want is fixed width(11 digits). 2 Decimal points. No positive sign. Negative sign included in fixed width.
What I have tried:
{0:00000000.00;0:0000000.00;0:00000000.00}
Please tell me what is the right way to do this.
You can use section modifiers to give the output you need:
string format = "{0:00000000.00;-0000000.00}";
Console.WriteLine(string.Format(format, 1.2));
Console.WriteLine(string.Format(format, .2));
Console.WriteLine(string.Format(format, -.2));
Console.WriteLine(string.Format(format, 12.0));
Console.WriteLine(string.Format(format, -0.0));
Console.WriteLine(string.Format(format, 12.555));
Prints out:
00000001.20
00000000.20
-0000000.20
00000012.00
00000000.00
00000012.56
It's basically {position:postive format;negative format;zero format}
Note: position is only used for formatted strings, you can also use it with double.ToString(string) without the "position" element;
If zero format is not provided, format for positive format section is used to format Zero.
See https://msdn.microsoft.com/en-us/library/0c899ak8(v=vs.110).aspx for more detail about the ; section format.
string.Format("{0:00000000.00}", 1.2)
works fine for me
You'll need a second format section for negative numbers. Declaring it as a Func or extension method might be helpful if you need to reuse it. Like so:
using System;
using System.Linq;
using System.Text;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
Func<double, string> toFixedWidth = (d) => {
return string.Format("{0:00000000.00;-0000000.00}", d);
};
foreach (var d in new double[] { 1.2, 0.2, -0.2, 12, 0, -0, 12.555 })
{
Console.WriteLine(toFixedWidth(d));
}
}
}
}
00000001,20
00000000,20
-0000000,20
00000012,00
00000000,00
00000000,00
00000012,56
Press any key to continue . . .
double d = -12.365;
string s = d.ToString("0:00000000.00"); //-0:00000012.37
string sOut = d.ToString("00000000.00"); //-00000012.37
Here's a general function for this. It works the same as the other answers, but it builds the formatting string dynamically based on the length (total length) and decimals parameters.
public static string FormatDoubleAsFixedLengthString(double value, int length, int decimals)
{
int wholeDigits = length - decimals;
// Provide a spot for the negative sign if present.
if (value < 0)
{
wholeDigits--;
}
string wholeDigitsFormat = new String('0', wholeDigits);
string decimalDigitsFormat = new String('0', decimals);
string format = $"{{0:{wholeDigitsFormat}.{decimalDigitsFormat}}}";
return string.Format(format, value);
}
And while we're at it, here's the same function but for integers:
public static string FormatIntAsFixedLengthString(int value, int length)
{
// Provide a spot for the negative sign if present.
if (value < 0)
{
length--;
}
return string.Format($"{{0:D{length}}}", value);
}
Related
In C# I want a function that rounds a given double to a given amount of decimals. I always want my function to return a value (which can be a string) with the given amount of decimals. If necessary, trailing zeros need to be added.
Example:
string result = MyRoundingFunction(1.01234567, 3);
// this must return "1.012"
That's easy, it's just rounding and converting to string. But here comes the problem:
string result2 = MyRoundingFuntion(1.01, 3);
// this must return "1.010"
Is there a convenient/standard way to do this, or do I manually need to add trailing zeros?
Any help is appreciated. Note that in the real life application I can't hard code the number of decimals.
You can create a formatter like this example:
int numDigitsAfterPoint = 5;
double num = 1.25d;
string result = num.ToString("0." + new string('0', numDigitsAfterPoint));
or (more easily)
string result = num.ToString("F" + numDigitsAfterPoint);
As a sidenote, ToString uses the MidpointRounding.AwayFromZero instead of the MidpointRounding.ToEven (also called Banker's Rounding). As an example:
var x1 = 1.25.ToString("F1");
var x2 = 1.35.ToString("F1");
var x3 = Math.Round(1.25, 1).ToString();
var x4 = Math.Round(1.35, 1).ToString();
These will produce different result (because Math.Round normally uses MidpointRounding.ToEven)
And note that internally ToString() seems to do some "magic" before rounding digits. For doubles, if you ask him less than 15 digits, I think it rounds to 15 digits first and then rounds to the right number of digits. See here https://ideone.com/ZBEis9
You should first round, then format.
String.Format("{0:0.000}", Math.Round(someValue, 2));
What you should read is:
Math.Round
String.Format, Custom Numeric Format
As option you could use the extension to support that
Extension Methods
string.format("{0:f2}", value);
Your solution (does what you want).
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
string result = MyRoundingFunction(1.01234567, 3);
Console.WriteLine(result);
result = MyRoundingFunction(1.01, 3);
Console.WriteLine(result);
Console.ReadLine();
}
public static string MyRoundingFunction(double value, int decimalPlaces)
{
string formatter = "{0:f" + decimalPlaces + "}";
return string.Format(formatter, value);
}
}
}
Simply:
decimal.Round(mydouble, 2).ToString("0.00")
I need to write values like:
9.6 x 10²
9.6 x 10¹²
I need to know if there is a way to format numbers as above in a string.
You have to find the appropriate character from the code page you are using, for example UTF-8:
string superScript2 = "²";
There is no such thing as formatting in a string, it is just all data.
Try this:
public static string Eng(this double x, string format="g")
{
const string sup_signs = "⁺⁻⁼⁽⁾ⁿ";
const string sup_digits = "⁰¹²³⁴⁵⁶⁷⁸⁹";
if(double.IsNaN(x) || double.IsInfinity(x))
{
return x.ToString();
}
int num_sign = Math.Sign(x);
x = Math.Abs(x);
// group exponents in multiples of 3 (thousands)
int exp = (int)Math.Floor(Math.Log(x, 10)/3)*3;
// otherwise use:
// int exp = (int)Math.Floor(Math.Log(x, 10));
// and handle the exp==1 case separetly to avoid 10¹
x*= Math.Pow(10, -exp);
int exp_sign = Math.Sign(exp);
exp = Math.Abs(exp);
// Build the exponent string 'dig' from right to left
string dig = string.Empty;
while(exp>0)
{
int n = exp%10;
dig = sup_digits[n] + dig;
exp = exp/10;
}
// if has exponent and its negative prepend the superscript minus sign
if(dig.Length>0 && exp_sign<0)
{
dig = sup_signs[1] + dig;
}
// prepend answer with minus if number is negative
string sig = num_sign<0 ? "-" : "";
if(dig.Length>0)
{
// has exponent
return $"{sig}{x.ToString(format)}×10{dig}";
}
else
{
// no exponent
return $"{sig}{x.ToString(format)}";
}
}
As a test case run
static void Main(string[] args)
{
// Type code here.
double x = Math.PI/50e5;
for(int i = 0; i < 20; i++)
{
// Format output to 12 wide column, right aligned
Debug.WriteLine($"{ Eng(x, "g4"),12}");
x*=50;
}
}
with the output:
628.3×10⁻⁹
31.42×10⁻⁶
1.571×10⁻³
78.54×10⁻³
3.927
196.3
9.817×10³
490.9×10³
24.54×10⁶
1.227×10⁹
61.36×10⁹
3.068×10¹²
153.4×10¹²
7.67×10¹⁵
383.5×10¹⁵
19.17×10¹⁸
958.7×10¹⁸
47.94×10²¹
2.397×10²⁴
119.8×10²⁴
By no means optimized, but it does the job. The exponents are in engineering form (multiples of 3 only, in order to avoid things like 10¹). As a bonus, the number can be formatted to a specific number of significant digits by supplying a format code like g4 or g5 for 4 or 5 digits respectively.
It can handle negative or positive numbers
It can handle negative or positive exponents of 10
In can format the mantissa
It can handle NAN or Inf.
It's in extension form for re-usability
As a follow up to my comment above - does something like this do what you require :
public String FormatAs10Power(decimal val)
{
string SuperscriptDigits = "\u2070\u00b9\u00b2\u00b3\u2074\u2075\u2076\u2077\u2078\u2079";
string expstr = String.Format("{0:0.#E0}", val);
var numparts = expstr.Split('E');
char[] powerchars = numparts[1].ToArray();
for (int i = 0; i < powerchars.Length; i++)
{
powerchars[i] = (powerchars[i] == '-') ? '\u207b' : SuperscriptDigits[powerchars[i] - '0'];
}
numparts[1] = new String(powerchars);
return String.Join(" x 10",numparts);
}
See : https://dotnetfiddle.net/dX7LAF
As per my comment above - the number is first converted to an exponential format string (https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings#EFormatString), that string is then split on the exponential separator 'E'. The first array is the numeric part, the second the power of 10 to which it is raised - this is converted to superscript characters using one of the techniques of the link I gave (Convert a string/integer to superscript in C#), converted back to a string & the two parts combined using "x 10" as the new separator.
I have assumed you want the value to single digit precision as per your example with no preceding + sign. If you need anything else you could pass the format as a parameter. The code for superscript + is '\u207A'. There is a link here (at the time of writing) giving the list of superscript codes : http://unicode.org/charts/PDF/U2070.pdf
I am trying to count how many zeroes are a before a decimal.
private void textBox1_TextChanged(object sender, EventArgs e)
{
decimal x = 0;
if (Decimal.TryParse(textBox1.Text, out x))
{
var y = 1000000;
var answer = x * y;
displayLabel2.Text = (x.ToString().Replace(".", "").TrimStart(new Char[] { '0' }) + "00").Substring(0, 2);
}
else
{
displayLabel2.Text = "error";
}
}
When I plug in (lets say) 7.2 I get an output that displays 72, which is what I want. Now I need another display. That initial 7.2 is being multiplied by 1000000. So the quotent of that would be 7,200,000.00. Now I need to some how count the 5 zeroes before the decimal point and display 5 for that. Then if I were to do .72. My Quotent would be 720,000.00. And I would need to display 4, for the 4 zeroes. And so on. Then I need to output that number to displayLabel5.Text
Here's a one line Linq you could try to count zeroes before the decimal. You can Split() first by the decimal then perform a Where().Count() to get the number of zeros.
using System;
using System.Linq;
public class Program
{
public static void Main()
{
string myString = (720000.00).ToString();
Console.WriteLine(myString.Split('.')[0].Where(d => d == '0').Count());
}
}
Results:
4
Demo
Quick and dirty code so be careful, but AFAIK this is the fastest way to do it.
// Input assuming you've sanitised it
string myInputString = "720000.00";
// Remove the decimals
myInputString = myInputString.Substring(0, myInputString.IndexOf("."));
// The count
int count = 0;
// Loop through and count occurrences
foreach (char c in myInputString)
{
if (c == "0")
{
count++;
}
}
Count is now 4.
Guarantee you this is faster than Regex ;-)
Edit: Sorry for the multiple edits, it's been a long day. Need coffee.
use a regular expression to find all the zeros before the period, then get the string length of that match.
Regex regex = new Regex(#"(0+)\.?");
string value1 = "7,200,000.00";
value1 = value1.Replace(",",""); //get rid of the commas
Match match = regex.Match(value1);
if (match.Success)
{
Console.WriteLine(match.Value.Length);
}
As always test the code because I wrote it just now here in this little text box and not in actual visual studio where I could compile and test it myself. But this should at least illustrate the methodology.
Edit:
slight tweak to the regex to account for the possibility that the number will not display a decimal point at all.
Due to a requirement I need very exact precision of a double value to a 4 decimal places as follows:
double myDoubleValue = 50234.9489898997952932;
From the above, I need the output as 50234.9489. I DON'T want Rounding the number in this requirement.
I came across with "Math.Truncate(a * 100) / 100;". But really i'm not interested with this approach.
I'm looking for better approach very simple way something like using String.Format or with Regular Expressions etc.
double d = 50234.94895345345345;
var Expected_result = Double.Parse((Regex.Match(d.ToString(), "[+-]?\\d*.\\d{0,4}")).Value);
You would need to do this yourself. One of the possible solutions would be to use an extension method
public static class DoubleEx
{
public static double TruncateFraction(this double value, int fractionRound)
{
double factor = Math.Pow(10, fractionRound);
return Math.Truncate(value * factor) / factor;
}
}
And this is how to use it
double foo = 50234.9489898997952932;
double bar = foo.TruncateFraction(4);
Console.WriteLine(foo); //50234.9489898997952932
Console.WriteLine(bar); //50234.9489
Without regexes:
This works very much fine for any double combinations
using System.Globalization;
class Program
{
static void Main(string[] args)
{
double d = 50234.9489898997952932;
char probablyDot = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator[0];
string[] number = d.ToString().Split(probablyDot);
//Console.WriteLine(number[0] + probablyDot + number[1].Remove(4));
Console.WriteLine(number[0] + probablyDot + (number.Length >1 ? (number[1].Length>4? number[1].Substring(0,4):number[1]): "0000"));
//Output: 50234.9489
Console.ReadKey();
}
}
There are a lot of answers here that work with the input given in the question, but on testing them with a range of values, they all have limitations (see comments).
The only way I can see to achieve this with any decimal input is the following. It might not be a one liner, but it seems robust to me.
private static string TrimDecimalPlaces(double value, int numberOfDecimalPlaces)
{
string valueString = value.ToString();
if (!valueString.Contains(".")) return valueString;
int indexOfDot = valueString.IndexOf(".");
if ((indexOfDot + numberOfDecimalPlaces + 1) < valueString.Length)
{
return valueString.Remove(indexOfDot + numberOfDecimalPlaces + 1);
}
return valueString;
}
I've tested this with the following test data and the results are as expected:
1
1.1
1.11
1.111
1.1111
1.11111
1.111111
-1
-1.1
-1.11
-1.111
-1.1111
-1.11111
-1.111111
In C# I want a function that rounds a given double to a given amount of decimals. I always want my function to return a value (which can be a string) with the given amount of decimals. If necessary, trailing zeros need to be added.
Example:
string result = MyRoundingFunction(1.01234567, 3);
// this must return "1.012"
That's easy, it's just rounding and converting to string. But here comes the problem:
string result2 = MyRoundingFuntion(1.01, 3);
// this must return "1.010"
Is there a convenient/standard way to do this, or do I manually need to add trailing zeros?
Any help is appreciated. Note that in the real life application I can't hard code the number of decimals.
You can create a formatter like this example:
int numDigitsAfterPoint = 5;
double num = 1.25d;
string result = num.ToString("0." + new string('0', numDigitsAfterPoint));
or (more easily)
string result = num.ToString("F" + numDigitsAfterPoint);
As a sidenote, ToString uses the MidpointRounding.AwayFromZero instead of the MidpointRounding.ToEven (also called Banker's Rounding). As an example:
var x1 = 1.25.ToString("F1");
var x2 = 1.35.ToString("F1");
var x3 = Math.Round(1.25, 1).ToString();
var x4 = Math.Round(1.35, 1).ToString();
These will produce different result (because Math.Round normally uses MidpointRounding.ToEven)
And note that internally ToString() seems to do some "magic" before rounding digits. For doubles, if you ask him less than 15 digits, I think it rounds to 15 digits first and then rounds to the right number of digits. See here https://ideone.com/ZBEis9
You should first round, then format.
String.Format("{0:0.000}", Math.Round(someValue, 2));
What you should read is:
Math.Round
String.Format, Custom Numeric Format
As option you could use the extension to support that
Extension Methods
string.format("{0:f2}", value);
Your solution (does what you want).
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
string result = MyRoundingFunction(1.01234567, 3);
Console.WriteLine(result);
result = MyRoundingFunction(1.01, 3);
Console.WriteLine(result);
Console.ReadLine();
}
public static string MyRoundingFunction(double value, int decimalPlaces)
{
string formatter = "{0:f" + decimalPlaces + "}";
return string.Format(formatter, value);
}
}
}
Simply:
decimal.Round(mydouble, 2).ToString("0.00")