11

I have a number, for example 1234567897865; how do I max it out and create 99999999999999 ?

I did this this way:

        int len = ItemNo.ToString().Length;
        String maxNumString = "";

        for (int i = 0; i < len; i++)
        {
            maxNumString += "9";
        }

        long maxNumber = long.Parse(maxNumString);

what would be the better, proper and shorter way to approach this task?

bfavaretto
  • 71,580
  • 16
  • 111
  • 150
Andrew
  • 7,619
  • 13
  • 63
  • 117

4 Answers4

11
long maxNumber = long.Parse(new String('9', ItemNo.ToString().Length));
Tudor
  • 61,523
  • 12
  • 102
  • 142
  • 1
    Like your answer better than accepted one. Why bother with FPU when CPU can do. More predictable than floating point, less testing headache. Helps to save some electricity as well –  Mar 29 '12 at 02:36
11
var x = 1234567897865;  
return Math.Pow(10, Math.Ceiling(Math.Log10(x+1e-6))) - 1;

To expand on comments below, if this problem was expressed in hex or binary, it could be done very simply using shift operators

i.e., "I have a number, in hex,, for example 3A67FD5C; how do I max it out and create FFFFFFFF?"

I'd have to play with this to make sure it works exactly, but it would be something like this:

var x = 0x3A67FD5C;  
var p = 0;
while((x=x>>1)>0) p++;          // count how many binary values are in the number
  return (1L << 4*(1+p/4)) - 1; // using left shift, generate 2 to 
                                // that power and subtract one
Charles Bretana
  • 143,358
  • 22
  • 150
  • 216
  • BigInteger has comparable methods if you outgrow `long`. – Austin Salonen Mar 28 '12 at 21:24
  • 2
    This is incorrect. Due to the properties of the floating point arithmetic when `x=10^n` `log(x)` may be slightly smaller than n. When this happens your function returns `10^n-1` instead of `10^(n+1)-1`. For example in double precision arithmetic x=1000 gives 999 instead of 9999 because `log(1000) = 2.99999999999999955591e+00`. – Adam Zalcman Mar 28 '12 at 21:46
  • ahhh .... picky ! [but correct]. I fixed to handle this... @adam, why just just suggest/provide the fix yourself ?? – Charles Bretana Mar 28 '12 at 23:12
  • @CharlesBretana Yeah, this should fix it. – Adam Zalcman Mar 28 '12 at 23:15
  • 1
    @CharlesBretana I haven't edited the post, because I think it isn't very pretty to employ floating point to solve this in the first place. The fix with `1e-6` makes it even uglier. – Adam Zalcman Mar 28 '12 at 23:23
  • thats fair.. but, granted this is a very unusual, uncommon requirement, what solution would you recommend that might be prettier? The conversions to and from a string with string manipulation strikes me as even uglier. – Charles Bretana Mar 29 '12 at 01:10
  • on another note, the exact same requirement, but in binary or hex, would be considerably easier as it could be performed with 2 bitshifts and a final substraction... – Charles Bretana Mar 29 '12 at 01:12
  • @CharlesBretana See my answer below. – Adam Zalcman Mar 31 '12 at 14:40
  • @Adam, yes, thats along the lines I was thinking, except if problem is defined in Binary or hex, (not in base 10) it could be done with left shift operators and no math at all... see my edited answer – Charles Bretana Apr 15 '12 at 15:19
  • @CharlesBretana How about this: shift right by 1 and then or the result with the original, then shift that right by 2 and or the result with the result from the previous step, then shift right by 4 and or the result again, then shift right by 8,... you see the pattern. It requires the number of operations proportional to the logarithm in the number of bits. – Adam Zalcman Apr 15 '12 at 21:50
5

Try this:

int v = 1;
do {
    v = v * 10;
} while (v <= number);
return v - 1;
Adam Zalcman
  • 26,643
  • 4
  • 71
  • 92
1
int numDigits = (int)Math.Ceiling(Math.Log10(number));
int result = (int)(Math.Pow(10, numDigits) - 1)

I don't have a compiler available at the moment, so some additional string/double conversions may need to happen here.

Servy
  • 202,030
  • 26
  • 332
  • 449