473,395 Members | 1,608 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,395 software developers and data experts.

Portability question

Please humor a curious hobbyist.

Below is some code I made to amuse myself and reverse bit order. Any
comments or corrections are welcome, but I have some specific concerns.
I added the #define to try to make this portable. But what if I wanted to
*ensure* that my data type had 32 bits?
Would this be done in pre-processing?
If the 32-bit type turns out *not* to be unsigned long, how could I declare
p and r, and wouldn't my printf's and scanf be in trouble, too?
Are my concerns completely unfounded? Is there ever any valid reason to
*ensure* a specific bit count?
I really don't know where to begin, so a hint or a pointer to some relevant
example might be more fun that actually telling.

gcc -ansi -pedantic -lm rev.c
cat rev.c

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <limits.h>

#define LONG_BIT (CHAR_BIT * sizeof(unsigned long))

void print_binary( unsigned long n )
{
int i = 0;

for ( i = LONG_BIT - 1; i >= 0; i-- )
putchar( n & 1 << i ? '1' : '0' );
printf( "\n" );
}

int main( void )
{
unsigned long p = 0, r = 0;
int i;

for(;;)
{
p = pow( 2, LONG_BIT ) - 1;
r = 0;

printf( "\nEnter an integer value 0 to %lu or 'q' to
quit\n",
p );
if ( ! scanf( "%lu", &p ) )
{
if ( toupper( getchar() ) == 'Q' )
break;
puts( "Input error." );
while ( getchar() != '\n' );
continue;
}
while ( getchar() != '\n' );

for ( i = 0; i < LONG_BIT; i++ )
{
if ( p & ( 1 << i ) )
r |= ( 1 << ( LONG_BIT - 1 - i ) );
}

printf( "Value: %lu\n", p );
printf( "%-10s", "Binary:" );
print_binary( p );
printf( "%-10s", "Reversed:" );
print_binary( r );
}
return EXIT_SUCCESS;
}
Nov 14 '05 #1
5 2002
Stephen Mayes wrote:
But what if I wanted to
*ensure* that my data type had 32 bits?
I don't know why you are asking about 32 bits, since none of
your code contains any assumption of 32 bits. However,

You can only do that if there _is_ a 32-bit datatype...

If you use C99, you can use the <inttypes.h> header.
It #defines format specifiers for exact-width integer types
#defined in <stdint.h>, which it #includes.
It will declare the type uint32_t and #define the PRIu32 and SCNu32
macros with format specifiers if there is such a type.

Otherwise, you could use a type which has _at least_ 32 bits
(uint_least32_t and PRIuLEAST32, SCNuLEAST32), and remove unwanted bits
by hand (by doing 'value & 0xFFFFFFFFU').
Would this be done in pre-processing?
If the 32-bit type turns out *not* to be unsigned long, how could I
declare p and r, and wouldn't my printf's and scanf be in trouble,
too?
With C99, #ifdef PRIu32 or PRIuLEAST32 should get you there.
With older C versions, you can use

#include <limits.h>
#if UINT_MAX >= 0xFFFFFFFFUL
typedef unsigned int Uint32
# define UINT32_FMT ""
#else
typedef unsigned long Uint32
# define UINT32_FMT "l"
#endif

... printf("%" UINT32_FMT "u", some_Uint32_variable); ...

and, as I mentioned, mask away unwanted bits with '&'.
Are my concerns completely unfounded? Is there ever any valid reason
to *ensure* a specific bit count?
Sometimes. Usually it is enough to ensure 'at least X bits'.
#define LONG_BIT (CHAR_BIT * sizeof(unsigned long))
This value is too large if unsigned long has padding bits (bits which do
not contribute to the value). You need to count the number of bits in
ULONG_MAX. The readable way to do that is with a loop. The preprocessor
way to do it is IMAX_BITS(ULONG_MAX), with the following macro:

/* Number of bits in inttype_MAX, or in any (1<<b)-1 where 0 <= b < 3E+10 */
#define IMAX_BITS(m) ((m) /((m)%0x3fffffffL+1) /0x3fffffffL %0x3fffffffL *30 \
+ (m)%0x3fffffffL /((m)%31+1)/31%31*5 + 4-12/((m)%31+3))

IMAX_BITS(INT_MAX) computes the number of bits in an int, and
IMAX_BITS((unsigned_type)-1) computes the number of bits in an
unsigned_type. Until someone implements 4-gigabyte integers, anyway:-)

Explanation, where 'x**y' means x raised to the power of y:
Line 1 computes (number of whole 30-bit chunks) * 30:
For m = (2**(K*n+r))-1 and P = (2**K)-1 with K=30, P=0x3fffffff,
m = (P+1)**n * 2**r - 1,
m % P + 1 = 1 * 2**r - 1 + 1 = 2**r when 2**r-1<P so r<K,
m /(m%P+1) = (P+1)**n - 1
= ((P+1)-1) * ((P+1)**0 +...+ (P+1)**(n-1)),
.../P%P*K = ( 1**0 +...+ 1**(n-1)) % P * K
= n*K when n < P.
Part 2 does the same to the remainder (m%0x3fffffff) with K=5, P=31.
Part 3 "happens" to count the final 0-4 bits in m%31=[0/1/3/7/15].
m % 31 is short for m % 0x3fffffff % 31, because 0x3fffffff % 31 = 0.
0x3fffffffL is the largest portable 2**x-1 with such a 2**y-1 factor.
for ( i = LONG_BIT - 1; i >= 0; i-- )
putchar( n & 1 << i ? '1' : '0' );
1 << i should be 1UL << i or (some_wide_enough_unsigned_type)1 << i,
otherwise it will overflow if i < (number of bits in an int), or - since
you used a signed constant (1), if the 1 is shifted into the sign bit.
p = pow( 2, LONG_BIT ) - 1;
Since pow() is a floating-point function, the result is inaccurate.
Use ULONG_MAX or (unsigned long)-1.

If you wanted exactly 32 bits but use an integer type which may
be wider than that, I think you would need something like

((1UL << (LONG_BIT -1)) - 1) * 2 - 1
if ( ! scanf( "%lu", &p ) )
If you type Return, this will just keep waiting for you to type in a
number, since scanf(%lu) ignores preceding whitespace. I don't know if
that is what you want or not. If not, read one line into an input
buffer with fgets() (NOT gets()!) and use sscanf() to read the integer
from that buffer.
while ( getchar() != '\n' );
This will loop forever if you reach the end of the file.

int ch;
while ((ch = getchar()) != EOF && ch != '\n');

for ( i = 0; i < LONG_BIT; i++ )
{
if ( p & ( 1 << i ) )
r |= ( 1 << ( LONG_BIT - 1 - i ) );


Again, shift 1UL, not 1.

--
Hallvard
Nov 14 '05 #2
Hallvard B Furuseth wrote:
Stephen Mayes wrote:
But what if I wanted to
*ensure* that my data type had 32 bits?


I don't know why you are asking about 32 bits, since none of
your code contains any assumption of 32 bits. However,

You can only do that if there _is_ a 32-bit datatype...


unsigned long and long are guaranteed to be at least 32 bits.
Thus they can always hold a 32 bit type. Unsigned versions will
not run into UB, barring division by zero, but the signed versions
will.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #3

"Hallvard B Furuseth" <h.b.furuseth(nospam)@usit.uio(nospam).no> wrote in
message news:HB**************@bombur.uio.no...
Stephen Mayes wrote:
But what if I wanted to
*ensure* that my data type had 32 bits?


I don't know why you are asking about 32 bits, since none of
your code contains any assumption of 32 bits. However,


Thanks for all the input.
I've been looking at rfc1321 about md5. Section 2 mentions circularly
shifting a 32-bit *word*. That's where my brain was. I wanted to practice
a little bit-manipulating.
Are my concerns completely unfounded? Is there ever any valid reason
to *ensure* a specific bit count?


Sometimes. Usually it is enough to ensure 'at least X bits'.


I'm thinking that should be the case with md5. I probably wouldn't even
need to mask anything.
Thanks again.
Nov 14 '05 #4
Stephen Mayes wrote:

Please humor a curious hobbyist.

Below is some code I made to amuse myself and reverse bit order.
Any comments or corrections are welcome,
but I have some specific concerns.
I added the #define to try to make this portable.
But what if I wanted to *ensure* that my data type had 32 bits?


The simplest portable way to reverse the bits of an object
with an arbitrary number of bytes, of arbitrary width,
is to reverse the order of the bits of each byte,
and then reverse to order of the bytes.

rev_byte.c will reverse the order of bits, in bytes of any width:

http://groups.google.com/groups?selm...mindspring.com

--
pete
Nov 14 '05 #5
CBFalconer wrote:
unsigned long and long are guaranteed to be at least 32 bits.
True. I assumed he meant _exactly_ 32 bits, or at least as
few bits more as necessary.
Thus they can always hold a 32 bit type. Unsigned versions will
not run into UB, barring division by zero, but the signed versions
will.


Yup. Bit fiddling with signed numbers should be avoided.

--
Hallvard
Nov 14 '05 #6

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

Similar topics

7
by: fabio de francesco | last post by:
Hi, I'm not a professional programmer, but I've been writing C/C++ and Ada programs for a few years on GNU/Linux without ever concerning on standards and portability to other OSs. I've always...
21
by: asm | last post by:
Hi All, Like typdef, does C have further support for portability? Thanks, ASM
93
by: roman ziak | last post by:
I just read couple articles on this group and it keeps amazing me how the portability is used as strong argument for language cleanliness. In my opinion, porting the program (so you just take the...
25
by: Stephen Mayes | last post by:
From lurking on this most excellent newsgroup, I have garnered that an expressed benefit of having a standard is portability of code. I see a lot of open source endeavors that inspire my awe, but I...
93
by: jacob navia | last post by:
In this group there is a bunch of people that call themselves 'regulars' that insist in something called "portability". Portability for them means the least common denominator. Write your code...
239
by: Eigenvector | last post by:
My question is more generic, but it involves what I consider ANSI standard C and portability. I happen to be a system admin for multiple platforms and as such a lot of the applications that my...
46
by: Bill Cunningham | last post by:
I have heard that return -1 is not portable. So what would be the answer to portability in this case? What about exit(0) and exit (-1) or exit (1)? Or would it be best to stick with C's macros,...
2
by: DiAvOl | last post by:
Hello everyone, I read here and there that bit-field usage should be avoided because it's not portable. My question is why it's not portable? For example let's say I have a struct in my code...
80
by: jacob navia | last post by:
Several people in this group argue that standard C is not portable since there are no compilers for it, etc. I propose this program in Standard C, that I have compiled in several OSes to test if...
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...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

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.