Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Macro that test BCDness evaluating its argument only once

Reply
Thread Tools

Macro that test BCDness evaluating its argument only once

 
 
Francois Grieu
Guest
Posts: n/a
 
      01-18-2007
This macro returns 1 if the low 8 bits of x form a valid BCD value,
and 0 otherwise.

#define VALIDBCD(x) (((x)&0x0F)<0x0A && ((x)&0xF0)<0xA0)

How do you rewrite it so that it evaluates its argument only once,
requires no temp variable or table, and is fully C99 compliant?

My shortest solution uses 3 constants, and beats the original
hands off in term of performance on my desktop CPU.
I wish my C compilers would know this kind of optimization.


François Grieu
 
Reply With Quote
 
 
 
 
Thad Smith
Guest
Posts: n/a
 
      01-20-2007
Francois Grieu wrote:
> This macro returns 1 if the low 8 bits of x form a valid BCD value,
> and 0 otherwise.
>
> #define VALIDBCD(x) (((x)&0x0F)<0x0A && ((x)&0xF0)<0xA0)
>
> How do you rewrite it so that it evaluates its argument only once,
> requires no temp variable or table, and is fully C99 compliant?


Here's one way:

#define VALBCD(x) !((((((x)&0xff)*0x201)&0x1ef0)+0xc60)&0x2100)

> My shortest solution uses 3 constants, and beats the original
> hands off in term of performance on my desktop CPU.


You got me beat! I'd be interested in seeing your version.

--
Thad
 
Reply With Quote
 
 
 
 
Thad Smith
Guest
Posts: n/a
 
      01-20-2007
Francois Grieu wrote:
> This macro returns 1 if the low 8 bits of x form a valid BCD value,
> and 0 otherwise.
>
> #define VALIDBCD(x) (((x)&0x0F)<0x0A && ((x)&0xF0)<0xA0)
>
> How do you rewrite it so that it evaluates its argument only once,
> requires no temp variable or table, and is fully C99 compliant?


Just after posting, I realized that the lsb of each digit isn't needed, so

#define VALIDBCD(x) !((((x)&0xee)+0x66)&0x110)

--
Thad
 
Reply With Quote
 
Francois Grieu
Guest
Posts: n/a
 
      01-20-2007
In article <45b1ab9a$0$58034$(E-Mail Removed) s.com>,
Thad Smith <(E-Mail Removed)> wrote:

> Francois Grieu wrote:
> > This macro returns 1 if the low 8 bits of x form a valid BCD value,
> > and 0 otherwise.
> >
> > #define VALIDBCD(x) (((x)&0x0F)<0x0A && ((x)&0xF0)<0xA0)
> >
> > How do you rewrite it so that it evaluates its argument only once,
> > requires no temp variable or table, and is fully C99 compliant?

>
> #define VALIDBCD(x) !((((x)&0xee)+0x66)&0x110)


Yes, that's the best I could find in term of number of constants and
operators.
If the code is to run on an 8-bit machine, this likely is more efficient:
#define VALIDBCD(x) !((((x)>>1&0x77)+0x33)&0x8

Rather amazingly, even when sizeof(x) is 2, my usual embedded C
compiler (Metrowerks) needs no explicit cast to unsigned char
to make this generate a perfect stream of single-byte arithmetic/logic
operations.

Francois Grieu
 
Reply With Quote
 
Thad Smith
Guest
Posts: n/a
 
      01-20-2007
Francois Grieu wrote:
> In article <45b1ab9a$0$58034$(E-Mail Removed) s.com>,
> Thad Smith <(E-Mail Removed)> wrote:
>
>
>>Francois Grieu wrote:
>>
>>>This macro returns 1 if the low 8 bits of x form a valid BCD value,
>>>and 0 otherwise.
>>>
>>>#define VALIDBCD(x) (((x)&0x0F)<0x0A && ((x)&0xF0)<0xA0)
>>>
>>>How do you rewrite it so that it evaluates its argument only once,
>>>requires no temp variable or table, and is fully C99 compliant?

>>
>>#define VALIDBCD(x) !((((x)&0xee)+0x66)&0x110)

>
> If the code is to run on an 8-bit machine, this likely is more efficient:
> #define VALIDBCD(x) !((((x)>>1&0x77)+0x33)&0x8


Good point.

> Rather amazingly, even when sizeof(x) is 2, my usual embedded C
> compiler (Metrowerks) needs no explicit cast to unsigned char
> to make this generate a perfect stream of single-byte arithmetic/logic
> operations.


I'm not surprised. On an 8-bit machine it pays to know when the
calculations can be done properly with a single byte. The shift and
both AND operators ensure that. The biggest test is knowing that the
sum with 0x33 gets truncated to 8 bits in the following operation so
that the upper byte isn't needed.

--
Thad
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
problem in running a basic code in python 3.3.0 that includes HTML file Satabdi Mukherjee Python 1 04-04-2013 07:48 PM
Py_XDECREF/Py_DECREF evaluating its argument more than once Chris Angelico Python 0 05-06-2011 12:51 AM
Reformulating a macro to use argument just once Francois Grieu C Programming 17 01-19-2007 02:33 PM
Reformulating a macro to use argument just once Francois Grieu C Programming 9 01-17-2007 01:20 PM
test test test test test test test Computer Support 2 07-02-2003 06:02 PM



Advertisments