(First of all: this is not a duplicate of Format numbers with floating points and sign in textbox in C#)
I am using the solution from dodald (https://stackoverflow.com/a/27510646/3179989) for formatting numbers with floating points and sign to make them aligned based on the floating point:
textbox1.Text = String.Format("{0:+;-}{0,9:0.00000;0.00000}", number1);
textbox2.Text = String.Format("{0:+;-}{0,9:0.00000;0.00000}", number2);
textbox3.Text = String.Format("{0:+;-}{0,9:0.00000;0.00000}", number3);
textbox4.Text = String.Format("{0:+;-}{0,9:0.00000;0.00000}", number4);
textbox5.Text = String.Format("{0:+;-}{0,9:0.00000;0.00000}", number5);
It works perfectly for numbers are like -1.23456 (results in "- 1.23456"), however if the number is 1.2, then this will change it to "+ 1.20000".
Questions:
Is there anyway to avoid any extra zeros?
How can I add a space at the end of the text by using the formatting parameters and not using (text + " ")?
Thanks in advance
EDIT: to clarify this here is what I am looking for:
-123.123456
+ 1.123456
- 0.123456
- 0.123
+ 1.1
- 12.123456
I have multiple textboxes that are vertically aligned. I want the numbers to be displayed the way is presented above where the position of the floating point is always fixed and vertically aligned. The solution provided by dodald (https://stackoverflow.com/a/27510646/3179989) works just for the number with five decimal numbers like -1.23456 (results in "- 1.23456"), however if the number is 1.2, then his solution will change it to "+ 1.20000". I'd like to remove the added zeros to the string.
You can use this code by using string builder and you will find that all zeros on the right side of decimal point deleted and this is shown before (1555454545445.20000000000000000) and after (1555454545445.2) in console:
static void Main(string[] args)
{
string input = "1555454545445.20000000000000000";
StringBuilder sb = new StringBuilder(input);
for (int i = 0; i < input.Length-2; i++)
{
if (input[i] == '.')
{
if (input[input.Length - 1] == '0')
{
for (int x = 0; x < input.Length - i; i++)
{
if (sb[sb.Length - 1] == '0')
{
sb = sb.Remove((sb.Length - 1), 1);
}
}
}
}
}
Console.WriteLine(input);
Console.WriteLine(sb.ToString());
}
You can also use this code for removing any additional zeros on the right of the decimal point by using regular expression:
class MainProgram
{
public static void Main(string[] args)
{
decimal DNumber = 1223456.45600000M;
Console.WriteLine("Original Decimal Number = {0}, Decimal Number Without Zeros = {1}", DNumber, DNumber.ToString("#.##############"));
Console.Read();
}
}
Related
In C# 4.0, whenever I compare two strings which have one or more trailing slashes, the comparison gives incorrect results:
String a = "1/2.1/";
String b = "1/2/";
if (a.CompareTo(b) > 0)
MessageBox.Show("Correct: " + a + " > " + b);
else
MessageBox.Show("Not correct: " + a + " <= " + b);
a = a.TrimEnd('/');
b = b.TrimEnd('/');
if (a.CompareTo(b) > 0)
MessageBox.Show("Trailing slash removed. Correct: " + a + " > " + b);
else
MessageBox.Show("Trailing slash removed. Not correct: " + a + " <= " + b);
Lexically speaking, "1/2.1/" comes after "1/2/", and there is not much question about that.
This behaviour also occurs in other places, such as sorting a datatable using the Select method.
Am I doing something wrong? Or is this a bug in .Net?
It should not even have anything to do with culture-specific information etc. since a slash is part of the most basic US ASCII character set.
I am running into this when comparing SQL Server hierarchyIDs. It's easy enough to solve but it is a somewhat astonishing problem.
Lexically speaking, "1/2.1/" comes after "1/2/", and there is not much question about that.
Why would it come after? On the ASCII chart, the / comes immediately after the ..
Given the following two strings, they're equal until you reach the 4th character. Then the / and . are compared, and the / is greater. So the result you're seeing (a < b) is actually correct.
1/2.1/
1/2/
After calling TrimEnd(), you end up with two different strings where and a > b.
1/2.1
1/2
If my old skill in C doesn't fail me, I think that CompareTo executes a character by character subtraction of the Integer value of the characters until the result is not zero.
After the first 3 identical characters the CompareTo looks at the fourth character, and this is a point for the first string and a slash for the second string.
The integer value of the point character is 46 while the integer value of the slash is 47, 46-47 gives back -1 so "1/2.1/" is less than "1/2/".
You can compare strings containing numbers if the numbers are right aligned:
01/02.00/
01/02.10/
01/10.00/
If this is not possible, consider creating a type for your numbers
public class ChapterNumber : IComparable<ChapterNumber>
{
private readonly decimal[] _number;
public ChapterNumber(params decimal[] number)
{
_number = number;
}
public int CompareTo(T obj)
{
var other = obj as ChapterNumber;
if (other == null) {
return +1;
}
int len = Math.Min(_number.Length, other._number.Length);
for (int i = 0; i < len; i++) {
int result = _number[i].CompareTo(other._number[i]);
if (result != 0) {
return result;
}
}
return _number.Length.CompareTo(other._number.Length);
}
public override ToString()
{
return String.Join('/', _number) + "/";
}
}
Usage:
var a = new ChapterNumber(1, 2.1m);
var b = new ChapterNumber(1, 2);
if (a.CompareTo(b) > 0) {
...
}
Is it possible in C# to format a double value with double.ToString in a way that I have always a fixed number of digits, no matter on which side of the decimal point?
Say I wish 6 digits, I want to have these results:
0.00123456789 gives "0.00123"
1.23456789 gives "1.23457"
123.456789 gives "123.457"
0.0000000123456789 gives "0.00000"
12345678.9 gives "12345679" (on overflow I want to see all digits left of decimalpoint)
4.2 gives "4.20000"
I'm experimenting with double.ToString, but cannot find any suitable format string.
Already tried "G6" (gives sometimes exponential format), "F6" (comes close, but 0.123456789 gives "0.123457" which are 7 digits).
I think some of your examples are wrong.
But I still think that I understand what you want to achieve.
I made an extension method.
public static class StringExtensionMethods
{
public static string ToString(this double d, int numberOfDigits)
{
var result = "";
// Split the number.
// Delimiter can vary depending on locale, should consider this and not use "."
string[] split = d.ToString().Split(new string[] { "." }, StringSplitOptions.None);
if(split[0].Count() >= numberOfDigits)
{
result = split[0].Substring(0, numberOfDigits);
}
else
{
result = split[0];
result += ".";
result += split[1];
// Add padding.
while(result.Count() < numberOfDigits +1)
result += "0";
result = result.Substring(0, numberOfDigits + 1);
}
return result;
}
}
I ran it with your examples:
double d0 = 0.00123456789;
double d1 = 1.23456789;
double d2 = 123.456789;
double d3 = 0.0000000123456789;
double d4 = 12345678.9;
double d5 = 4.2;
Console.WriteLine(d0.ToString(6));
Console.WriteLine(d1.ToString(6));
Console.WriteLine(d2.ToString(6));
Console.WriteLine(d3.ToString(6));
Console.WriteLine(d4.ToString(6));
Console.WriteLine(d5.ToString(6));
This is the output:
0.00123
1.23456
123.456
1.23456
123456
4.20000
I don't think this is the best way to solve it, but I like extension methods.
DoubleConverter class: http://1drv.ms/1yEbvL4
If your goal is to avoid "jumping" of the decimal point:
Use g formating, this does the most sensible thing to do
See where the decimal point is in your resulting string
pad with spaces at the beginning to align the column at the decimal point
As I understand, there is no predefined format that does what I need. So for everyone who is interested, here is the function I ended up with:
public string FormatValue(double d, int noOfDigits)
{
double abs = Math.Abs(d);
int left = abs < 1 ? 1 : (int)(Math.Log10(abs) + 1);
int usedDigits = 0;
StringBuilder sb = new StringBuilder();
for(; usedDigits < left; usedDigits++)
{
sb.Append("0");
}
if(usedDigits < noOfDigits)
{
sb.Append(".");
for(; usedDigits < noOfDigits; usedDigits++)
{
sb.Append("0");
}
}
return d.ToString(sb.ToString());
}
I need to convert numbers into a comma separated format to display in C#.
For Example:
1000 to 1,000
45000 to 45,000
150000 to 1,50,000
21545000 to 2,15,45,000
How to achieve this in C#?
I tried the below code:
int number = 1000;
number.ToString("#,##0");
But it is not working for lakhs.
I guess you can do this by creating a custom number format info for your needs
NumberFormatInfo nfo = new NumberFormatInfo();
nfo.CurrencyGroupSeparator = ",";
// you are interested in this part of controlling the group sizes
nfo.CurrencyGroupSizes = new int[] { 3, 2 };
nfo.CurrencySymbol = "";
Console.WriteLine(15000000.ToString("c0", nfo)); // prints 1,50,00,000
if specifically only for numbers then you could also do
nfo.NumberGroupSeparator = ",";
nfo.NumberGroupSizes = new int[] { 3, 2 };
Console.WriteLine(15000000.ToString("N0", nfo));
Here's a similar thread to yours add commas in thousands place for a number
and here's the solution that worked perfectly for me
String.Format("{0:n}", 1234);
String.Format("{0:n0}", 9876); // no decimals
If you want to be unique and do extra work that you don't have to here is a function I created for integer numbers you can place commas at whatever interval you want, just put 3 for a comma for each thousandths or you could alternatively do 2 or 6 or whatever you like.
public static string CommaInt(int Number,int Comma)
{
string IntegerNumber = Number.ToString();
string output="";
int q = IntegerNumber.Length % Comma;
int x = q==0?Comma:q;
int i = -1;
foreach (char y in IntegerNumber)
{
i++;
if (i == x) output += "," + y;
else if (i > Comma && (i-x) % Comma == 0) output += "," + y;
else output += y;
}
return output;
}
Have you tried:
ToString("#,##0.00")
Quick and dirty way:
Int32 number = 123456789;
String temp = String.Format(new CultureInfo("en-IN"), "{0:C0}", number);
//The above line will give Rs. 12,34,56,789. Remove the currency symbol
String indianFormatNumber = temp.Substring(3);
An easy solution would be to pass a format into the ToString() method:
string format = "$#,##0.00;-$#,##0.00;Zero";
decimal positiveMoney = 24508975.94m;
decimal negativeMoney = -34.78m;
decimal zeroMoney = 0m;
positiveMoney.ToString(format); //will return $24,508,975.94
negativeMoney.ToString(format); //will return -$34.78
zeroMoney.ToString(format); //will return Zero
Hope this helps,
How can I display the number with just the 2 not=zero decimals?
Example:
For 0.00045578 I want 0.00045 and for 1.0000533535 I want 1.000053
There is no built in formatting for that.
You can get the fraction part of the number and count how many zeroes there are until you get two digits, and put together the format from that. Example:
double number = 1.0000533535;
double i = Math.Floor(number);
double f = number % 1.0;
int cnt = -2;
while (f < 10) {
f *= 10;
cnt++;
}
Console.WriteLine("{0}.{1}{2:00}", i, new String('0', cnt), f);
Output:
1.000053
Note: The given code only works if there actually is a fractional part of the number, and not for negative numbers. You need to add checks for that if you need to support those cases.
My solution would be to convert the number to a string. Search for the ".", then count zeroes till you find a non-zero digit, then take two digits.
It's not an elegant solution, but I think it will give you consistent results.
Try this function, using parsing to find the # of fractional digits rather than looking for zeros (it works for negative #s as well):
private static string GetTwoFractionalDigitString(double input)
{
// Parse exponential-notation string to find exponent (e.g. 1.2E-004)
double absValue = Math.Abs(input);
double fraction = (absValue - Math.Floor(absValue));
string s1 = fraction.ToString("E1");
// parse exponent peice (starting at 6th character)
int exponent = int.Parse(s1.Substring(5)) + 1;
string s = input.ToString("F" + exponent.ToString());
return s;
}
You can use this trick:
int d, whole;
double number = 0.00045578;
string format;
whole = (int)number;
d = 1;
format = "0.0";
while (Math.Floor(number * Math.Pow(10, d)) / Math.Pow(10, d) == whole)
{
d++;
format += "0";
}
format += "0";
Console.WriteLine(number.ToString(format));
In my C# program I have a double obtained from some computation and its value is something like 0,13999 or 0,0079996 but this value has to be presented to a human so it's better displayed as 0,14 or 0,008 respectively.
So I need to round the value, but have no idea to which precision - I just need to "throw away those noise digits".
How could I do that in my code?
To clarify - I need to round the double values to a precision that is unknown at compile time - this needs to be determined at runtime. What would be a good heuristic to achieve this?
You seem to want to output a value which is not very different to the input value, so try increasing numbers of digits until a given error is achieved:
static double Round(double input, double errorDesired)
{
if (input == 0.0)
return 0.0;
for (int decimals = 0; decimals < 17; ++decimals)
{
var output = Math.Round(input, decimals);
var errorAchieved = Math.Abs((output - input) / input);
if (errorAchieved <= errorDesired)
return output;
}
return input;
}
}
static void Main(string[] args)
{
foreach (var input in new[] { 0.13999, 0.0079996, 0.12345 })
{
Console.WriteLine("{0} -> {1} (.1%)", input, Round(input, 0.001));
Console.WriteLine("{0} -> {1} (1%)", input, Round(input, 0.01));
Console.WriteLine("{0} -> {1} (10%)", input, Round(input, 0.1));
}
}
private double PrettyRound(double inp)
{
string d = inp.ToString();
d = d.Remove(0,d.IndexOf(',') + 1);
int decRound = 1;
bool onStartZeroes = true;
for (int c = 1; c < d.Length; c++ )
{
if (!onStartZeroes && d[c] == d[c - 1])
break;
else
decRound++;
if (d[c] != '0')
onStartZeroes = false;
}
inp = Math.Round(inp, decRound);
return inp;
}
Test:
double d1 = 0.13999; //no zeroes
double d2 = 0.0079996; //zeroes
double d3 = 0.00700956; //zeroes within decimal
Response.Write(d1 + "<br/>" + d2 + "<br/>" + d3 + "<br/><br/>");
d1 = PrettyRound(d1);
d2 = PrettyRound(d2);
d3 = PrettyRound(d3);
Response.Write(d1 + "<br/>" + d2 + "<br/>" + d3 +"<br/><br/>");
Prints:
0,13999
0,0079996
0,00700956
0,14
0,008
0,007
Rounds your numbers as you wrote in your example..
I can think of a solution though it isn't very efficient...
My assumption is that you can tell when a number is in the "best" human readable format when extra digits make no difference to how it is rounded.
eg in the example of 0,13999 rounding it to various numbers of decimal places gives:
0
0.1
0.14
0.14
0.14
0.13999
I'd suggest that you could loop through and detect that stable patch and cut off there.
This method seems to do this:
public double CustomRound(double d)
{
double currentRound = 0;
int stability = 0;
int roundLevel = 0;
while (stability < 3)
{
roundLevel++;
double current = Math.Round(d, roundLevel);
if (current == currentRound)
{
stability++;
}
else
{
stability = 1;
currentRound=current;
}
}
return Math.Round(d, roundLevel);
}
This code might be cleanable but it does the job and is a sufficient proof of concept. :)
I should emphasise that that initial assumption (that no change when rounding) is the criteria we are looking at which means that something like 0.3333333333 will not get rounded at all. With the examples given I'm unable to say if this is correct or not but I assume if this is a double issues that the problem is with the very slight variations from the "right" value and the value as a double.
Heres what I tried:
public decimal myRounding(decimal number)
{
double log10 = Math.Log10((double) number);
int precision = (int)(log10 >= 0 ? 0 : Math.Abs(log10)) + (number < 0.01m ? 1 : 2);
return Math.Round(number, precision);
}
test:
Console.WriteLine(myRounding(0.0000019999m)); //0.000002
Console.WriteLine(myRounding(0.0003019999m)); //0.0003
Console.WriteLine(myRounding(2.56777777m)); //2.57
Console.WriteLine(myRounding(0.13999m)); //0.14
Console.WriteLine(myRounding(0.0079996m)); //0.008
You can do it without converting to string. This is what I created fast:
private static double RoundDecimal(double number)
{
double temp2 = number;
int temp, counter = 0;
do
{
temp2 = 10 * temp2;
temp = (int)temp2;
counter++;
} while (temp < 1);
return Math.Round(number, counter < 2 ? 2 : counter);
}
or
private static double RoundDecimal(double number)
{
int counter = 0;
if (number > 0) {
counter = Math.Abs((int) Math.Log10(number)) + 1;
return Math.Round(arv, counter < 2 ? 2 : counter);
}
After giving it another thought I did the following and looks like it does what I want so far.
I iterate over the number of digits and compare Round( value, number ) and Round( value, number + 1 ). Once they are equal (not == of course - I compare the difference against a small number) then number is the number of digits I'm looking for.
Double.ToString() can take a string format as an argument. This will display as many characters as you require, rounding to the decimal place. E.G:
double Value = 1054.32179;
MessageBox.Show(Value.ToString("0.000"));
Will display "1054.322".
Source
Generic formats (i.e, pre-generated)
How to generate custom formats
You can use no of digits with Math.Round Function
Double doubleValue = 4.052102;
Math.Round(doubleValue, 2);
This will return 4.05 as your required answer.
This is tested code, can u explain me how i am wrong. So i need to change.