Dynamic number format in .NET? - c#

I have a problem and cant find a solution. I have numbers (decimal) like 85.12343 or 100 or 1.123324. I want to format this in a way that the result is always 13 chars long including the separator.
100 --> 100.000000000
1.123324 --> 1.12332400000
I tried with toString, but failed. How could I do this?
Thanks :)

int digits = 13;
decimal d = 100433.2414242241214M;
int positive = Decimal.Truncate(d).ToString().Length;
int decimals = digits - positive - 1; //-1 for the dot
if (decimals < 0)
decimals = 0;
string dec = d.ToString("f" + decimals);
It will not remove digits from the whole part, only the fraction, when needed.

I'd go with Kobi's answer, unless it's possible you could have more than 13 digits to start with, in which case you might need to do something like this (warning: I have not even attempted to make this efficient; surely there are ways it could be optimized if necessary):
public static string ToTrimmedString(this decimal value, int numDigits)
{
// First figure out how many decimal places are to the left
// of the decimal point.
int digitsToLeft = 0;
// This should be safe since you said all inputs will be <= 100M anyway.
int temp = decimal.ToInt32(Math.Truncate(value));
while (temp > 0)
{
++digitsToLeft;
temp /= 10;
}
// Then simply display however many decimal places remain "available,"
// taking the value to the left of the decimal point and the decimal point
// itself into account. (If negative numbers are a possibility, you'd want
// to subtract another digit for negative values to allow for the '-' sign.)
return value.ToString("#." + new string('0', numDigits - digitsToLeft - 1));
}
Example inputs/output:
Input Output
---------------------------------------
100 100.000000000
1.232487 1.23248700000
1.3290435309439872321 1.32904353094
100.320148109932888473 100.320148110
0.000383849080819849081 .000383849081
0.0 .000000000000

Quick 'n' dirty:
return (value.ToString("0.#") + "0000000000000").Substring(0, 13);

string formatted = original.ToString("0.000000000000").Remove(13);

Besides simply padding the string you can do some more elaborate math to determine the number of digits:
String FormatField(Int32 fieldWidth, Decimal value) {
var integerPartDigits =
value != Decimal.Zero ? (int) Math.Log10((Double) value) + 1 : 1;
var fractionalPartDigits = Math.Max(0, fieldWidth - integerPartDigits - 1);
return value.ToString("F" + fractionalPartDigits);
}
Note that if the value is negative or has an integer part with one less digit than the field width you will not get the desired result. However, you can modify the code to accommodate these cases based on exactly how you want to format and align these numbers.

What about
string newString;
if (original.ToString().Length >= 13)
{
newString = original.ToString().Substring(13);
}
else
{
newString = original.ToString().PadRight(13, '0');
}

int noofdecimal=3;
double value=1567.9800
value.ToString("#." + new string('0', noofdecimal));
//Result=1567.980

Related

How can I get the last two digits of any 3+ digit integer?

I'm trying to get the last two digits of an int that is a minimum of 3 digits long. Here is my (rather sloppy) attempt:
char[] number = num.ToString().ToCharArray();
int firstnum;
int secondnum;
string strLastTwoDigits = "";
int intLastTwoDigits;
firstnum = number[number.ToString().Length - 1];
secondnum = number[number.ToString().Length - 2];
strLastTwoDigits = (firstnum.ToString() + secondnum.ToString());
intLastTwoDigits = int.Parse(strLastTwoDigits);
The num variable is the number I'm trying to get the last two digits of. I'm trying to turn them into strings and use the string functions to do it, probably not the way it's done. The logic to check whether it's 3 digits or more isn't included, I don't need help with that, just getting those last two digits.
Any ideas?
Do you need those two numbers as a String? Or do you plan to convert them back to a number.
Because if you want to have a number at the end, just use the modulo- operator %.
You can find an example on how to use it here: https://www.dotnetperls.com/modulo
Edit: to state the obvious: last2 = number % 100;
Just perform a modulo operation.
var intLastTwoDigits = num % 100;
You can use the modulo of that number, it should be something like
int lastTwoDigits = num % 100;
This function will divide num / 100and gives you the rest as integer.
If you need the last to digits as int, you could just use modulo:
int lasttwo = num % 100;
the modulo operator (%) will return you the remainder of the division of one integer is by another - in this case your number divided by 100 - the remainder will always be the last two digits
If you want to use strings for that, string.Substring method will help you
var numString = num.ToString();
var strLastTwoDigits = numString.Substring(numString.Length - 2, 2);
var intLastTwoDigits = int.Parse(strLastTwoDigits);
Another (and more simpler option) is to use remainder % operator for that
int intLastTwoDigits = num % 100;
You get a remainder of division into 100, because you need the 2 last digits

Format string with decimal

I am trying to take a string that may or may not contain a '.' to x amount of characters removing the "decimal point" as well. the result will ultimately be converted to a signed integer. I will also always need to the 1/10 decimal (ie 10 will become 100, 1 will become 10, etc...) I would like to just format the string without converting to an integer until the very end.
Example
if my incoming string is
9.86
I want 98 as a string ( i don't care about rounding up or anything)
if i get 9
I want 90
if i get -100
i want -1000
if i get -95.353
i want -953
string.Format("{0:d}", (int)9.015*10);
If you want a rounded result, replace the Cast
Edit: But I missed the "string" part. Verbose code below
var input = "9.86";
var len = input.IndexOf('.');
var result = "";
if (len > 0)
{
result = input.Substring(0, len);
result += input.Substring(len + 1, 1);
}
else
{
result = input + "0";
}
If you are essentially multiplying by ten the number contained in the string and dropping decimal places after the first, then you would be better off casting the string as a decimal and then doing the conversion and casting that number as an integer. Otherwise you will have to write a large set of mathematical rules on how to modify your string based on a particular type of input.
string[] input = {"9.86", "9", "-100", "-95.3"};
List<int> intNums = new List<int>();
foreach (string s in input)
{
decimal number;
if (Decimal.TryParse(s, out number))
{
number = number * 10;
intNums.Add((int)number);
}
}
Output:
[0] 98 int
[1] 90 int
[2] -1000 int
[3] -953 int

Counting Precision Digits

How to count precision digits on a C# decimal type?
e.g. 12.001 = 3 precision digits.
I would like to thrown an error is a precision of greater than x is present.
Thanks.
public int CountDecPoint(decimal d){
string[] s = d.ToString().Split('.');
return s.Length == 1 ? 0 : s[1].Length;
}
Normally the decimal separator is ., but to deal with different culture, this code will be better:
public int CountDecPoint(decimal d){
string[] s = d.ToString().Split(Application.CurrentCulture.NumberFormat.NumberDecimalSeparator[0]);
return s.Length == 1 ? 0 : s[1].Length;
}
You can get the "scale" of a decimal like this:
static byte GetScale(decimal d)
{
return BitConverter.GetBytes(decimal.GetBits(d)[3])[2];
}
Explanation: decimal.GetBits returns an array of four int values of which we take only the last one. As described on the linked page, we need only the second to last byte from the four bytes that make up this int, and we do that with BitConverter.GetBytes.
Examples: The scale of the number 3.14m is 2. The scale of 3.14000m is 5. The scale of 123456m is 0. The scale of 123456.0m is 1.
If the code may run on a big-endian system, it is likely that you have to modify to BitConverter.GetBytes(decimal.GetBits(d)[3])[BitConverter.IsLittleEndian ? 2 : 1] or something similar. I have not tested that. See the comments by relatively_random below.
I know I'm resurrecting an ancient question, but here's a version that doesn't rely on string representations and actually ignores trailing zeros. If that's even desired, of course.
public static int GetMinPrecision(this decimal input)
{
if (input < 0)
input = -input;
int count = 0;
input -= decimal.Truncate(input);
while (input != 0)
{
++count;
input *= 10;
input -= decimal.Truncate(input);
}
return count;
}
I would like to thrown an error is a precision of greater than x is present
This looks like the simplest way:
void AssertPrecision(decimal number, int decimals)
{
if (number != decimal.Round(number, decimals, MidpointRounding.AwayFromZero))
throw new Exception()
};

Finding the number of places after the decimal point of a Double

I have a Double value:
double a = 4.5565;
What is the easiest way to calculate the number of digits after the decimal point (4 in this case).
I know that I can convert to string and do a split and take the length. But is there an easier way?
There's no easy way, especially since the number of digits mathematically speaking might be far more than displayed. For example, 4.5565 is actually stored as 4.556499999999999772626324556767940521240234375 (thanks to harold for calculating that). You're very unlikely to find a useful solution to this problem.
EDIT
You could come up with some algorithm that works like this: if, as you calculate the decimal representation, you find a certain number of 9s (or zeros) in succession, you round up (or down) to the last place before the series of 9s (or zeros) began. I suspect that you would find more trouble down that road than you would anticipate.
var precision = 0;
var x = 1.345678901m;
while (x*(decimal)Math.Pow(10,precision) !=
Math.Round(x*(decimal)Math.Pow(10,precision)))
precision++;
precision will be equal to the number of significant digits of the decimal value (setting x to 1.23456000 will result in a precision of 5 even though 8 digits were originally specified in the literal). This executes in time proportional to the number of decimal places. It counts the number of fractional digits ONLY; you can count the number of places to the left of the decimal point by taking the integer part of Math.Log10(x). It works best with decimals as they have better value precision so there is less rounding error.
Write a function
int CountDigitsAfterDecimal(double value)
{
bool start = false;
int count = 0;
foreach (var s in value.ToString())
{
if (s == '.')
{
start = true;
}
else if (start)
{
count++;
}
}
return count;
}
I think this might be a solution:
private static int getDecimalCount(double val)
{
int i=0;
while (Math.Round(val, i) != val)
i++;
return i;
}
double val9 = 4.5565d; int count9 = getDecimalCount(val9);//result: 4
Sorry for the duplication -> https://stackoverflow.com/a/35238462/1266873
base on james answer bat much clearer:
int num = dValue.ToString().Length - (((int)dValue).ToString().Length + 1);
num is the exact number of digits after the decimal point.
without including 0 like this(25.520000)
in this case, you will get num= 2
I Think String solution is best : ((a-(int)a)+"").length-2
I'll perhaps use this code if I needed,
myDoubleNumber.ToString("R").Split('.')[1].Length
"R" here is Round Trip Format Specifier
We need to check for the index bounds first of course.
Another solution would be to use some string functions:
private int GetSignificantDecimalPlaces(decimal number, bool trimTrailingZeros = true)
{
var stemp = Convert.ToString(number);
if (stemp.IndexOf(Application.CurrentCulture.NumberFormat.NumberDecimalSeparator) < 0)
return 0;
if (trimTrailingZeros)
stemp = stemp.TrimEnd('0');
return stemp.Length - 1 - stemp.IndexOf(Application.CurrentCulture.NumberFormat.NumberDecimalSeparator);
}
Remember to use System.Windows.Forms to get access to Application.CurrentCulture

Format C# Double to Scientfic Notation in powers with multiples of three

I'm trying to format some large numbers in scientific format, but I need the power in multiples of three. Is there a recommended way to do this?
I have a range of numbers in a table and instead of true scientific format (with a single digit before the decimal point) I'm happy to have that change in order to have a power with a multiple of three, for example:
3.123e+003
19.523e+003
Rather than:
3.123e+003
1.952e+004
Having all the powers as multiples of three makes my table easier to scan, I believe.
Thanks in advance
I think you need to write your own function.
At first you can get the scientific representation of the number with the precision two digits larger than you need.
Then you should parse resulting string to get floating-point coefficient and 10's power index as numbers of type decimal. After that you analyse the remainder of division index by 3 and change the numbers in the appropriate way. Finally you generate output string.
static string Scientific3(double value, int precision)
{
string fstr1 = "{0:E" + (precision+2).ToString() + "}";
string step1 = string.Format(fstr1, value);
int index1 = step1.ToLower().IndexOf('e');
if (index1 < 0 || index1 == step1.Length - 1)
throw new Exception();
decimal coeff = Convert.ToDecimal(step1.Substring(0, index1));
int index = Convert.ToInt32(step1.Substring(index1 + 1));
while(index%3!=0)
{
index--;
coeff *= 10;
}
string fstr2 = "{0:F" + precision.ToString() + "}E{1}{2:D3}";
return string.Format(fstr2, coeff, ((index < 0) ? "-" : "+"), Math.Abs(index));
}

Categories

Resources