I want with a given double number to return its "size" (known as |number|, or number of digit without the numbers after the dot), for example:
12.324654 -> 2
12 -> 2
0.99 -> 0
1.01 -> 1
901 -> 3
-0.99 -> 0
-9.999 -> 1
There must be a function is .net that I dont familiar with that does it..
Thanks.
Try log10(max(abs(number), 0.5)) + 1 rounded down.
Or, in actual C# syntax:
(int)(Math.Log10(Math.Max(Math.Abs(number), 0.5)) + 1)
OK, how does that work?
At first of all, p = log10(x) is the base-10 logarithm of x; that is to say, the value such that 10 raised to the p-th power (or 1 followed by p zeros) equals x. The logarithm essentially measures the length of the number, except that it's a smooth function of x:
(Note that, in languages that don't provide a base-10 logarithm function, we can always calculate it as log10(x) = log(x) / log(10), where log() is the logarithm function in any base.)
For example, we have
log10(1) = 0.0
log10(10) = 1.0
log10(100) = 2.0
log10(1000) = 3.0
but also e.g.:
log10(5) = 0.69897
log10(50) = 1.69897
log10(500) = 2.69897
log10(5000) = 3.69897
In general, n ≤ log10(x) < n+1 whenever 10n ≤ x < 10n+1.
Looking at the values above, it should be easy enough to see that, to get the number of base-10 digits in a whole number, we should round its base-10 logarithm down to the nearest whole number and add 1 (because we want the length of 10 to be 2, not 1).
However, there are a few more edge cases to consider:
First, the original questioner wanted the length of −x to equal the length of x. The logarithm is only defined for positive numbers, so we replace x by its absolute value to make it always positive.
Second, the original questioner also wanted the length of numbers between 0 and 1 to be zero. The logarithm, however, can take arbitrarily large negative values:
log10(0.1) = −1.0
log10(0.01) = −2.0
log10(0.001) = −3.0
log10(0.0001) = −4.0
and indeed, log10(0) = −∞. To satisfy this requirement, we simply make sure that the number whose length we calculate can never go below 0.5 by using the maximum of it and 0.5 as the input to log10(). (We could use any number between 0.1 and 1 as the cutoff, but 0.5 happens to be a nice round binary fraction.)
Also, we have to make sure to add +1 to the logarithm before rounding it, so that the number that we round is always non-negative. That's because (int)
in C# actually rounds negative numbers up towards zero. For example, since log10(0.5) ≈ −0.3, the expression (int)Math.Log10(0.5) + 1
(rounding before addition) would evaluate to 0+1 = 1 rather than the expected 0.
((int)Math.Abs(12.324654)).ToString().Length
Math.Abs
will convert to positive number (don't want to count the negative sign)(int)
will drop the digits following the decimal pointToString()
converts to a string ===> "12"Length
tells you how many characters there are
there is an edge case where (int)( some number ) == 0
, where the length is going to give you 1-- you may not want this, so be aware of the possibility
now, what you COULD do is make this an extention method....
public static class Utils
{
public static int Size(this double n)
{
int i = (int)Math.Abs(n);
if ( i == 0 ) return 0;
return i.ToString().Length;
}
}
12.324654.Size() == 2;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With