Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the size of a number in .net?

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.

like image 800
Nir Avatar asked Nov 29 '22 04:11

Nir


2 Answers

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:

Graph of the base-10 logarithm 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 10nx < 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) &approx; −0.3, the expression (int)Math.Log10(0.5) + 1 (rounding before addition) would evaluate to 0+1 = 1  rather than the expected 0.

like image 56
Ilmari Karonen Avatar answered Dec 15 '22 21:12

Ilmari Karonen


((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 point
ToString() 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;
like image 25
Muad'Dib Avatar answered Dec 15 '22 20:12

Muad'Dib