post  Integer number

makan007 (57)   Link to this post
If i want to remove last digit of a number:

I will use: n/=10

What about removing first digit of a number?
helios (6070)   Link to this post
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;
}
jsmith (3802)   Link to this post
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;
}

helios (6070)   Link to this post
But that leaves only the first digit. OP wants to [b]remove[/i] the first digit.
jsmith (3802)   Link to this post
Sorry, change all / to %.
chrisname (2547)   Link to this post
Is there an advantage to jsmith's code over helios' or vice versa?
Just curious.
jsmith (3802)   Link to this post
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

This topic is archived - New replies not allowed.