Is there a way using a string formatter to format Thousands, Millions, Billions to 123K, 123M, 123B without having to change code to divide value by Thousand, Million or Billion?
String.Format("{0:????}", LargeNumber)
There are different ways to achieve this, but for me the easiest and quickest is to use the "," custom specifier
double value = 1234567890;
// Displays 1,234,567,890
Console.WriteLine(value.ToString("#,#", CultureInfo.InvariantCulture));
// Displays 1,234,568K
Console.WriteLine(value.ToString("#,##0,K", CultureInfo.InvariantCulture));
// Displays 1,235M
Console.WriteLine(value.ToString("#,##0,,M", CultureInfo.InvariantCulture));
// Displays 1B
Console.WriteLine(value.ToString("#,##0,,,B", CultureInfo.InvariantCulture));
I use this mix of formats in an Extension Method (just add it to your project and enjoy) 😎
public static string ToKMB(this decimal num)
{
if (num > 999999999 || num < -999999999 )
{
return num.ToString("0,,,.###B", CultureInfo.InvariantCulture);
}
else
if (num > 999999 || num < -999999 )
{
return num.ToString("0,,.##M", CultureInfo.InvariantCulture);
}
else
if (num > 999 || num < -999)
{
return num.ToString("0,.#K", CultureInfo.InvariantCulture);
}
else
{
return num.ToString(CultureInfo.InvariantCulture);
}
}
Use:
((decimal)235).ToKMB();
// 235
((decimal)1235).ToKMB();
// 1.2K
((decimal)6271235).ToKMB();
// 6.27M
((decimal)93246571235).ToKMB();
// 93.247B
Notes:
It return more detail for bigger numbers and I like it.
It support negative numbers too. (Thanks to #Dusty for his note in comments.
I write a method for decimal numbers in this example, you can write some override methods for it to support int, long and double to use it without any casting such as:
myIntNumber.ToKMB();
myLongNumber.ToKMB();
myDoubleNumber.ToKMB();
myDecimalNumber.ToKMB();
You can implement a ICustomFormatter that divides the value by thousand, million or billion, and use it like this:
var result = string.Format(new MyCustomFormatter(), "{0:MyFormat}", number);
Related
I'm trying to write this in C#. The requirement is very straightforward - check if a string input is a value within the range from 0 to 100.
I want to make sure the string is either an integer value in the range of 0 to 100 or
a double that's within the same range as well.
So for example, these are the accepted values:
0
50
100
0.1
50.7
100.0
I checked the double.parse method here but not sure if it's the one I'm looking for: https://learn.microsoft.com/en-us/dotnet/api/system.double.tryparse?view=net-7.0#system-double-tryparse(system-string-system-iformatprovider-system-double#)
The reason is that it can also parse string like this one: 0.64e2 (which is 64)
Is this something that can be achieved with built-in library already?
Wrote you a little snippet:
// C# function to check if string is a percentage between 0 and 100
public static bool IsPercentage(string s)
{
// regex check if s is a string with only numbers or decimal point
if (Regex.IsMatch(s, #"^\d+\.?\d*$"))
{
double d = Convert.ToDouble(s);
return d >= 0 && d <= 100;
}
return false;
}
Also returns false if the string contains % or has exponential (e).
if my understanding of the Q was correct and exponential representations like mentioned "0.64e2" is unwanted:
static bool IsPercentage(string s)
{
if (Single.TryParse(s, NumberStyles.AllowLeadingSign |
NumberStyles.AllowDecimalPoint, NumberFormatInfo.InvariantInfo, out Single n))
return n >= 0 && n <= 100;
return false;
}
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
How do I get 12. from 12 value with standard .NET string formatting? I've tested 0.### and it does not work.
double number = 12;
string.Format("{0:0.###}", number); // returns "12" not "12."
double number = 12.345;
string.Format("{0:0.###}", number); // returns "12.345"
Currently I've resolved with string manipulation but is it somewhat possible with standard string.Format()?
Thanks.
I think you can first check if the double is actually and integer, and if yes, use a simple string.Format("{0}.", number):
double number = 12;
if (number % 1 == 0)
Console.Write(string.Format("{0}.", number));
C# demo
double number = 12;
string.Format((number % 1 == 0) ? "{0}." : "{0}", number);
Gives 12.
double number = 12.345;
string.Format((number % 1 == 0) ? "{0}." : "{0}", number);
Gives 12.345
I'm trying to write a piece of code in C# to find the number digits of a integer number, the code works perfectly for all numbers (negative and positive) but I have problem with 10, 100,1000 and so on, it shows one less digits than the numbers' actual number of digits. like 1 for 10 and 2 for 100..
long i = 0;
double n;
Console.Write("N? ");
n = Convert.ToInt64(Console.ReadLine());
do
{
n = n / 10;
i++;
}
while(Math.Abs(n) > 1);
Console.WriteLine(i);
Your while condition is Math.Abs(n) > 1, but in the case of 10, you are only greater than 1 the first time. You could change this check to be >=1 and that should fix your problem.
do
{
n = n / 10;
i++;
}
while(Math.Abs(n) >= 1);
Use char.IsDigit:
string input = Console.ReadLine();
int numOfDigits = input.Count(char.IsDigit);
What's wrong with:
Math.Abs(n).ToString(NumberFormatInfo.InvariantInfo).Length;
Indeed, converting a number to a string is computationally expensive compared to some arithmetic, but it is hard to deal with negative nubers, overflow,...
You need to use Math.Abs to make sure the sign is not counted, and it is a safe option to use NumberFormatInfo.InvariantInfo so that for instance certain cultures that use spaces and accents, do not alter the behavior.
public static int NumDigits(int value, double #base)
{
if(#base == 1 || #base <= 0 || value == 0)
{
throw new Exception();
}
double rawlog = Math.Log(Math.Abs(value), #base);
return rawlog - (rawlog % 1);
}
This NumDigits function is designed to find the number of digits for a value in any base. It also includes error handling for invalid input. The # with the base variable is to make it a verbatim variable (because base is a keyword).
Console.ReadLine().Replace(",", String.Empty).Length;
this will count all the char in a string
int amount = 0;
string input = Console.ReadLine();
char[] chars = input.ToArray();
foreach (char c in chars)
{
amount++;
}
Console.WriteLine(amount.ToString());
Console.ReadKey();
Need to display the values in the floating point format as well as in exponential format
if the value is greater or equal to 0.01 and less than or equal to 1000
display in the expotential format else display in the floating format
For eg : 3.230000000 is displayed as 3.23
0.00001 is displayed as 1E-05
But the problem with my code if number given is 1 then the number is displayed as 1.00.
if (dValue >= 0.01|| dValue <= 1000.0)
return (string.Format("{0:0.##E+00}", dValue));
else
return (string.Format("{0:F2}", dValue));
Please let me know how to check the number does not contain decimal values
Round the number to two decimal places and to an integer, and see if the results are "close enough":
if (dValue >= 0.01 && dValue <= 1000.0)
{
if (Math.Abs(Math.Round(dValue, 2) - Math.Round(dValue, 0)) < 0.005) {
return string.Format("{0:F0}", dValue);
else
return string.Format("{0:F2}", dValue);
}
else return (string.Format("{0:0.##E+00}", dValue));
The thing to note here is that (as always with floating point numbers) the comparison between the two rounded results should not be an equality comparison.
Replace your last line
return (string.Format("{0:F2}", dValue))
to
return (string.Format("{0:0.##}", dValue))
Consider simply using G format.
Or use Math.Truncate to get integral part, that see if it ie the same as original number (need to take into account output format precision to do comparison with desider eps, probably 0.005 in your case).
Too much time. :)
You will get 2 digits maximum with values like 3.234.
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Format(0.00001));
Console.WriteLine(Format(1));
Console.WriteLine(Format(3.2));
Console.WriteLine(Format(3.22));
Console.WriteLine(Format(3.256));
Console.ReadLine();
}
static string Format(double dValue)
{
if (dValue >= 0.01 && dValue <= 1000.0)
{
int temp = (int)Math.Round(dValue * 100);
if (temp % 100 == 0)
return ((int)dValue).ToString();
else if (temp % 10 == 0)
return (string.Format("{0:F1}", dValue));
else
return (string.Format("{0:F2}", dValue));
}
else
return (string.Format("{0:0.##E+00}", dValue));
}
}
gives
1E-05
1
3,2
3,22
3,26
Probably there are cleaner solutions?!