I too agree.
...open toolbox...rummage, rummage...ahh, here's an occassionally handy tool
right here that I wrote quite some time ago.
/*
Convert the numeric arguments into decimal,
octal, hexadecimal, and binary.
A octal number is prefixed with "0".
A hex number is prefixed with "0x" or "0X".
A binary number is prefixed with "0b" or "0B".
*/
Enjoy!
Tony Hansen
ihnp4!pegasus!hansen
P.S. Some notes on portability: This program makes use of two
non-universally available features. The first is strtol(), which is very
similar to atol() except that it can be set to check the first two
characters for "0", "0x" or "0X" and adjust the base accordingly. Public
domain versions of this routine have been posted in the past. An alternative
is to write your own. Another alternative is to check for these prefixes
separately and parallel btol() with otol() and xtol().
The second is the value HIBITL taken from <values.h>. This is simply a long
with the highest bit turned on. One way of getting it is to use:
#define HIBITL ((unsigned long)(~((unsigned long)~0>>1)))
Some people may be able to find a similar value in <limits.h>.
#!/bin/sh
# This is a shar archive.
# The rest of this file is a shell script which will extract:
#
# octhex.c
#
# To extract the files from this shell archive file simply
# create a directory for this file, move the archive file
# to it and enter the command
#
# sh filename
#
# The files will be extracted automatically.
# Note: Do not use csh.
#
# Archive created: Thu Apr 16 14:37:22 EDT 1987
#
echo x - octhex.c
sed 's/^X//' > octhex.c << '~FUNKY STUFF~'
/*
Convert the numeric arguments into decimal,
octal, hexadecimal, and binary.
A octal number is prefixed with "0".
A hex number is prefixed with "0x" or "0X".
A binary number is prefixed with "0b" or "0B".
*/
#include <stdio.h>
#include <values.h>
long strtol();
/* print out the number */
void prnum(i)
long i;
{
unsigned long mask;
printf("%d 0%o 0x%x 0b", i, i, i);
/* print a number as a bit pattern */
for (mask = HIBITL; mask != 0; mask >>= 1)
if ((i & mask) != 0)
putchar('1');
else
putchar('.');
putchar('\n');
}
/* convert a number specified by a bit pattern into a long. */
long btol(s)
char *s;
{
unsigned long i = 0;
for (s += 2; *s; s++)
{
i <<= 1;
if (*s == '1')
i |= 1;
}
return i;
}
main(argc,argv)
int argc;
char **argv;
{
while (--argc)
{
char *num = *++argv;
if (num[0] == '0' && (num[1] == 'b' || num[1] == 'B'))
prnum(btol(num));
else
prnum(strtol(num, (char**)NULL, 0));
}
return 0;
}
~FUNKY STUFF~
ls -l octhex.c
# The following exit is to ensure that extra garbage
# after the end of the shar file will be ignored.
exit 0
One of the great things about writing your very own C compiler, is that you
get the source code! And with the source code you can CHANGE things, and one
of the few things I did to my C compiler, was to add in binary constants, as
in 0b1001111. I figure, If I ever give one of my programs to anybody worth
his weight, he could figure out what I meant, and change it, or if he had
source code to his compiler, add binary constants as a feature...
People of the net unite; someone, post the diffs to the Vax, and/or System V C
compiler to add binary constants, and everyone else, patch your C compiler, so
that it can understand binary constants, after all it will only make your C
compiler bigger by a few bytes, and you haver the memory to burn. Do you want
to be one of the only people left with an outdated C compiler that does not
understand binary constants?
Please, no flames; read the above as an attemt to get people seriously
thinking about a nice feature. The use of such a feature, until it is widely
supported, should be used with a little bit of caution; such as if anybody
posts a program to net.source (or whatever they call it this week) with a
0b111011 in it, they should expect to get flames!
--
Mike Stump, Cal State Univ, Northridge Comp Sci Department
uucp: {sdcrdcf, ihnp4, hplabs, ttidca, psivax, csustan}!csun!aeusemrs
0R<Roman Numerals>
So that it would be valid to say:
pagenumber = 0rvii; /* pagenumber = 7 */
etc. At the same time I also added a special routine which would
take 0f<base>.<number>. The "f" is "fix radix", base is the number
base to use, and number is the number in "base" base. So:
0f12.10 = 12 (decimal)
0f0x10.10 = 0f16.10 = 16(decimal) /*note imbedded reference 0x..*/
0f2.10 = 2 (decimal)
and
"0f18." would consist of the set of { 0123456789abcdefgh } digits.
Note, this method only worked up to base 36. I forget what I did
with "0f0." and "0f1.".
This could get really complicated quickly, but think how good it
would do for the C obfustication awards!
I don't think I ever implemented printf & scanf functions to deal
with this kind of tripe.
Jon
-------------------------------
Disclaimer: Today, I'm probably insane (or at least I'll plead it that way),
who knows about tomorrow.
Addresses .. ucbvax!dual!unicom!physh
.. hplabs!well!physh
.. killer!ssbn!physh
During an investigation for arbitrary base notations (in SAIL, an
ALGOL-holics language), I had proposed: '<char>.<number> , where <char>
is the character for radix-1 (a must-be-representable character).
A C-like version might be: .<char>.number.
Thus .7.xxx is octal, .1.xxx is binary, .F.xxx is hex, .2.xxx is trinary,
and .0.xxx is unary (although it is not clear whether 0 is .0.0 or .0.).
The advantage of this representation is that it is radix-independent
(assuming there is a well-defined mapping of characters to digits); you
may unambiguously write a number down whatever the default radix.
FROM: Scott Daniels, Tektronix CAE
5302 Betsy Ross Drive, Santa Clara, CA 95054
UUCP: dan...@cae780.UUCP (Scott Daniels)
tektronix!teklds!cae780!daniels
{ihnp4, decvax!decwrl}!amdcad!cae780!daniels
{nsc, hplabs, resonex, qubix, leadsv}!cae780!daniels
For an example, instead of saying something like 143b9, say something
like rad_conv(143,9) (for those of you who like typing,
convert_to_radix(142,9)).
It doesn't read as well, but it is a portable solution. But that
shouldn't make a big difference, since such fine programmers as
ourselves <:-D minimize the number of instances of magik numbers in
our code.
"The Laughing Fool ( <:-D )" Silver
First: what are the precise semantics? Are they *exactly* the same as 0x?
This is not an entirely trivial question: remember the difference between
signed and unsigned, depending on whether a value is decimal or hex. Will
all compiler changers do it ``right''?
More important, what is to stop a compiler changer from adding more goodies,
say the proposed [...] notation for expressions which may not be optimised,
or subrange types, or ... ? I'm not saying any of these are bad, but what
happens to C's portability when every compiler accepts a peculiar language
of its own making? (I say this having, with great trepidation, added a number
of trivial language features to a BCPL compiler once. When I handed the
compiler over to another person, and went away for a month, I came back only
to find that the language accepted by the compiler had changed radically.)
There are certainly defects in C, as are there defects in UNIX (what good
can you say about a system call named 'creat'???) But the whole point in
standardisation is so that we can take code and run it on a new machine or
compiler, with no horde of #ifdefs protecting various quirky features.
Thanks, Mike, but no, thanks.
-----
Vincent Manis {seismo,uw-beaver}!ubc-vision!ubc-cs!manis
Dept. of Computer Science ma...@cs.ubc.cdn
Univ. of British Columbia manis%ubc....@csnet-relay.arpa
Vancouver, B.C. V6T 1W5 ma...@ubc.csnet
(604) 228-6770 or 228-3061
"Long live the ideals of Marxism-Lennonism! May the thoughts of Groucho
and John guide us in word, thought, and deed!"
>For an example, instead of saying something like 143b9, say something
>like rad_conv(143,9) (for those of you who like typing,
>convert_to_radix(142,9)).
>
>It doesn't read as well, but it is a portable solution.
Well, that almost does the trick. The problem is that there's no way
on many machines to use a macro to generate a string from a non-string.
If your macro was to call a function, you'd logicaly need to pass the
function a string, which would be impossible to generate. You'd need
to write:
rad_conv("149",9)
which would work fine for the case of passing the info to a function, but
really screws things up if you wanted to macro-substitute a true arbitrary
radix format constant on machines that support such things.
If you're going to use odd constants, it's best to define the constant
as a #define value (in base 10 or 16) and leave a comment as to what it
would be in the "other radix".
---
John Stanley (jo...@viper.UUCP)
Software Consultant - DynaSoft Systems
UUCP: ...{amdahl,ihnp4,rutgers}!{meccts,dayton}!viper!john