Integer number

Nov 13, 2009 at 8:09am
If i want to remove last digit of a number:

I will use: n/=10

What about removing first digit of a number?
Nov 13, 2009 at 10:01am
I actually took my time to thoroughly test this out. Contrary to what I initially thought, using floating point operations is massively (~1000 times) slower than converting the integer to a string or string-like array and omitting the last element. My computer can do this 450 million times per second if I inline the function, and 160 million times if I don't. Given that my CPU runs at 1.86 GHz, each call takes 4 clocks. Wow. Just amazing.

Here, you can have it:
1
2
3
4
5
6
7
8
9
10
template <typename T>
inline T method_B(T x){
	char conv[20];
	unsigned a=0;
	for (;x;x/=10)
		conv[a++]=x%10;
	for (unsigned b=a-2;b<a;b--)
		x=x*10+conv[b];
	return x;
}
Nov 13, 2009 at 2:40pm
At that point why not just hardcode it a bit (ok, this only works for one type):

1
2
3
4
5
6
7
8
9
10
11
12
13
unsigned method_C( unsigned x ) {
    return 
        x > 999999999U ? x / 1000000000 :
        x > 99999999U ? x / 100000000 :
        x > 9999999U ? x / 10000000 :
        x > 999999U ? x / 1000000 :
        x > 99999U ? x / 100000 :
        x > 9999U ? x / 10000 :
        x > 999U ? x / 1000 :
        x > 99U ? x / 100 :
        x > 9U ? x / 10 :
        x;
}

Nov 13, 2009 at 3:44pm
But that leaves only the first digit. OP wants to [b]remove[/i] the first digit.
Nov 13, 2009 at 7:19pm
Sorry, change all / to %.
Nov 13, 2009 at 7:41pm
Is there an advantage to jsmith's code over helios' or vice versa?
Just curious.
Nov 13, 2009 at 8:11pm
This would probably be the fastest in the general case (pardon the templates, just there for my sanity):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
template< unsigned P >
struct Power {
    enum { value = 10 * Power< P-1 >::value };
};

template<>
struct Power<0U> {
    enum { value = 1 };
};


unsigned remove_first( unsigned x ) {
    if( x >= Power<5>::value ) {
        if( x >= Power<7>::value ) {
            if( x >= Power<9>::value ) {
                return x % Power<9>::value;
            } else if( x >= Power<8>::value ) {
                return x % Power<8>::value;
            } else {
                return x % Power<7>::value;
            }
        } else if( x >= Power<6>::value ) {
            return x % Power<6>::value;
        } else {
            return x % Power<5>::value;
        }
    } else {
        if( x >= Power<3>::value ) {
            if( x >= Power<4>::value ) {
                return x % Power<4>::value;
            } else {
                return x % Power<3>::value;
            }
        } else if( x >= Power<1>::value ) {
            if( x >= Power<2>::value ) {
                return x % Power<2>::value;
            } else {
                return x % Power<1>::value;
            }
        } else {
            return x;
        }
    } 
}


The function will perform either 3 or 4 comparisons (for values between 10^8 and 10^9 - 1 it will be 4, for all others 3).
I suppose statistically speaking it could be made slightly faster still by flipping all the comparisons to less than, at which
point the worst case will be a much smaller range of inputs as opposed to the range 10^8...10^9-1.

But anyway, I'll file the above code under "solutions awaiting problems".

To be fair though, any numerical approach to the problem has the problem that it loses all zero digits in the number.
To get around this limitation, a string-based approach must be taken.
Last edited on Nov 13, 2009 at 8:11pm
Topic archived. No new replies allowed.