Get Value of Digit

  • Thread starter =?iso-8859-1?B?VG9t4XM=?=
  • Start date
?

=?iso-8859-1?B?VG9t4XM=?=

I have a Graphical User Interface program and I'm working with numbers
written in base-10.

Is there a better way than the following to get the digit value?

unsigned GetDigitValue( char const c )
{
switch ( c )
{
case '0': return 0;
case '1': return 1;
case '2': return 2;
case '3': return 3;
case '4': return 4;
case '5': return 5;
case '6': return 6;
case '7': return 7;
case '8': return 8;
case '9': return 9;
}

}

Any reason why the above code wouldn't be fully portable?

-Tomás
 
M

mlimber

Tomás said:
I have a Graphical User Interface program and I'm working with numbers
written in base-10.

Is there a better way than the following to get the digit value?

unsigned GetDigitValue( char const c )
{
switch ( c )
{
case '0': return 0;
case '1': return 1;
case '2': return 2;
case '3': return 3;
case '4': return 4;
case '5': return 5;
case '6': return 6;
case '7': return 7;
case '8': return 8;
case '9': return 9;
}

}

Any reason why the above code wouldn't be fully portable?

-Tomás

Assuming you've already done error checking so you're sure the
character is between '0' and '9', you could just do this:

return unsigned(c - '0');

Your code is indeed portable, albeit inelegant.

Cheers! --M
 
M

mlimber

mlimber said:
Tomás said:
I have a Graphical User Interface program and I'm working with numbers
written in base-10.

Is there a better way than the following to get the digit value?

unsigned GetDigitValue( char const c )
{
switch ( c )
{
case '0': return 0;
case '1': return 1;
case '2': return 2;
case '3': return 3;
case '4': return 4;
case '5': return 5;
case '6': return 6;
case '7': return 7;
case '8': return 8;
case '9': return 9;
}

}

Any reason why the above code wouldn't be fully portable?

-Tomás
[snip]
Your code is indeed portable, albeit inelegant.

.... and, to emphasize the point, possibly incorrect if you haven't done
error checking on c before entering this function. (What would happen
if c had a value of 'a'?)

Cheers! --M
 
C

Carlos Martinez Garcia

There are some character tables (ASCII, EBCDIC, ....), and you can't
assume what position occupies numeric characters. But in practice, in
all examples I know they have consecutive positions.
If you assume that, you can calcule offset with the first element:
Example:

You can get value 0 with the operation 0 - '0'
Then you can write your own sentence:
return c-'0'

I can't assure that in all the cases, numbers are consecutive in any
codification, but in all cases I know, they are.

There are other alternatives:
- using C's sscanf, but you must use a null terminating string
- using stringstream (you can construct a stringstream and then use the
operator >> )
 
C

Clark S. Cox III

There are some character tables (ASCII, EBCDIC, ....), and you can't
assume what position occupies numeric characters. But in practice, in
all examples I know they have consecutive positions.
If you assume that, you can calcule offset with the first element:
Example:

You can get value 0 with the operation 0 - '0'
Then you can write your own sentence:
return c-'0'

I can't assure that in all the cases, numbers are consecutive in any
codification, but in all cases I know, they are.

You *can* be sure that numbers are consecutive, as the standard
requires it. If c is a digit, then (c-'0') is guaranteed to produce the
value of that digit.
 
T

Tomás

I know a lot of people here seem to dismiss my efforts as "over-zealous
optimization", but considering the two alternatives:

unsigned GetDigitValue( char const c )
{
switch ( c )
{
case '0': return 0;
case '1': return 1;
case '2': return 2;
case '3': return 3;
case '4': return 4;
case '5': return 5;
case '6': return 6;
case '7': return 7;
case '8': return 8;
case '9': return 9;
}

}

unsigned GetDigitValue( char const c )
{
return c - '0';
}

Firstly, the first one would produce longer assembly code, right?
But which would execute faster. Let's say this function is used inline, and
that it's called several times a second as it's decoding Gigabytes of
information... which do you think would be faster?

My guess is that the second would be faster.

How do you usually test the speed of code, say if you've two functions that
achieve an aim by different methods?

-Tomás
 
B

Ben Pope

Tomás said:
I know a lot of people here seem to dismiss my efforts as "over-zealous
optimization", but considering the two alternatives:

unsigned GetDigitValue( char const c )
{
switch ( c )
{
case '0': return 0;
case '1': return 1;
case '2': return 2;
case '3': return 3;
case '4': return 4;
case '5': return 5;
case '6': return 6;
case '7': return 7;
case '8': return 8;
case '9': return 9;
}

}

unsigned GetDigitValue( char const c )
{
return c - '0';
}

Firstly, the first one would produce longer assembly code, right?
Probably.

But which would execute faster. Let's say this function is used inline, and

Well, the second is really easy to inline.
that it's called several times a second as it's decoding Gigabytes of
information... which do you think would be faster?

The second one.
My guess is that the second would be faster.

How do you usually test the speed of code, say if you've two functions that
achieve an aim by different methods?

Stick it in a loop and do it a million times. Your OS probably has
higher resolution timers than C++, so use the most appropriate.

Ben Pope
 
F

Fei Liu

Tomás said:
I know a lot of people here seem to dismiss my efforts as "over-zealous
optimization", but considering the two alternatives:

unsigned GetDigitValue( char const c )
{
switch ( c )
{
case '0': return 0;
case '1': return 1;
case '2': return 2;
case '3': return 3;
case '4': return 4;
case '5': return 5;
case '6': return 6;
case '7': return 7;
case '8': return 8;
case '9': return 9;
}

}

unsigned GetDigitValue( char const c )
{
return c - '0';
}

Firstly, the first one would produce longer assembly code, right?
But which would execute faster. Let's say this function is used inline, and
that it's called several times a second as it's decoding Gigabytes of
information... which do you think would be faster?

My guess is that the second would be faster.

How do you usually test the speed of code, say if you've two functions that
achieve an aim by different methods?

-Tomás

The 2nd implementation will be much faster because branching code often
leads to CPU pipeline stalls and dramatically decreases performance.
Although CPU branch prediction engine can alleviate some of the
problems but it's best to write code that contains no branching as in
implementation 2.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,434
Messages
2,571,690
Members
48,796
Latest member
Greg L.

Latest Threads

Top