473,379 Members | 1,367 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,379 software developers and data experts.

Macro that test BCDness evaluating its argument only once

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
Jan 18 '07 #1
4 1441
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
Jan 20 '07 #2
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
Jan 20 '07 #3
In article <45***********************@auth.newsreader.octanew s.com>,
Thad Smith <Th*******@acm.orgwrote:
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)&0x88)

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
Jan 20 '07 #4
Francois Grieu wrote:
In article <45***********************@auth.newsreader.octanew s.com>,
Thad Smith <Th*******@acm.orgwrote:

>>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)&0x88)
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
Jan 20 '07 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

25
by: Andrew Dalke | last post by:
Here's a proposed Q&A for the FAQ based on a couple recent threads. Appropriate comments appreciated X.Y: Why doesn't Python have macros like in Lisp or Scheme? Before answering that, a...
7
by: A. Saksena | last post by:
Hi all, Is it possible to write a function or a macro in C++, which is capable of accepting any number of arguments. To give an example, the following should be possible: - ...
7
by: Jim Cook | last post by:
We have a macro which takes various index constants as an argument and offsets into an array. The macro can be an Lvalue or Rvalue. The index is not zero based. I would like a compile time error...
14
by: Michael B Allen | last post by:
I just noticed that doing something like the following may fail because it can overwrite u->size before it's evaluated. memcpy(u, buf, u->size); Is it legit that this is a macro as opposed to...
17
by: Russell Shaw | last post by:
Hi, How do i make an if/then/else macro act as a function so that the whole thing looks like the return value? I tried this lame attempt for starters: #define A_FROM_B(b) \ ( \ if(b < 10)...
10
by: Praveen.Kumar.SP | last post by:
Hi Could anyone solve the problem for the code below The Code: #include "stdio.h" #include "iostream.h" void Temp( int a, char* str,...)
12
by: Laurent Deniau | last post by:
I was playing a bit with the preprocessor of gcc (4.1.1). The following macros expand to: #define A(...) __VA_ARGS__ #define B(x,...) __VA_ARGS__ A() -nothing, *no warning* A(x) -x ...
20
by: rkk | last post by:
Hi, Is there an equivalent typeof macro/method to determine the type of a variable in runtime & most importantly that works well with most known C compilers? gcc compiler supports typeof()...
9
by: Francois Grieu | last post by:
Consider this macro // check if x, assumed of type unsigned char, is in range #define ISVALID(x) ((x)>=0x20 && (x)<=0x7E) Of course, this can't be safely used as in if (ISVALID(*p++)) foo();...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.