#include <stdio.h>
#define loctype long
//#define loctype short
//#define loctype double
//#define loctype float
#define value 3735928559 //a fun value which turns into DEADBEEF in hex.
#define EOL 13
//Normally, of course, you would just printf in hex format:
// printf("%04X", value); //replace 04 with sizeof(value)
//But printf is ungodly huge and slow. If you need something tiny and faster...
char hexnibblea (unsigned char b) {
if (b>9) b+=('A'-10); else b+='0';
return b;
}
/* A good C compiler should generate something like
LOAD b
SUB #9
LOAD #55 ; 'A'-10
SKIP ABOVEZERO
LOAD #48 ; '0'
ADD b
SAVE b
You don't want to know what they really generate. *facepalm*
*/
//if you don't mind wasting some program memory:
#define hexnibble_m(b) "0123456789ABCDEF"[b]
// or if you will use it more than once:
char hexnibble (unsigned char b) {
return hexnibble_m(b);
}
void puts_hex_r(loctype h) { //type* & order agnostic, lsb first output
char i;
for (i = sizeof(loctype)*2-1; i>=0; i--) { //down count is faster
putchar(hexnibble
((unsigned char)h
&0xF)); h/=16; // easily optimized by most compilers
}
}
//the only problem with the above is that it is lsb first. And, as Aram notes:
//"a byte (8 bit value), does not have endianness so you do not reverse the nibbles.
// The correct output should be EFBEADDE00000000."
//Since our goal here is just to move data over an ASCII channel, we can ignore
//the byte order reversal.
//If you want msb first, and you have memory for a buffer:
//https://stackoverflow.com/a/36968534/663416
//otherwise...
//Note: the following code is horrific. pointers, order dependant, fails for floats.
void puts_hex_f(loctype h) {
char i;
unsigned char n;
unsigned char *p = (unsigned char *)&h+sizeof(loctype)-1;
for (i = sizeof(loctype)-1; i>=0; i--) {
n = p[0];
p--;
}
}
//slightly better is doing a union to join a byte array to the value
//Note: the following code is horrific. wastes memory, order dependant, no floats.
void puts_hex_f2(loctype h2) {
union {
loctype val;
unsigned char b[sizeof(loctype)];
} h;
h.val=h2;
char i;
for (i=sizeof(loctype)-1;i>=0;i--) {
}
}
//That isn't bad if you want to show the internal representation of a value...
//and again, if you have a buffer, life is grand
void puts_hex_b(loctype h) {
char buf[sizeof(loctype)*2+1];
char i;
buf[sizeof(loctype)*2+1]=0; //need a trailing zero to output via puts Thanks Aram!
for (i = sizeof(loctype)*2-1; i>=0; i--) { //down count is faster
buf[i] = hexnibble((unsigned char)h&0xF);
h/=16; // easily optimized by most compilers
}
}
int main(void) {
puts_hex_b(value);
puts_hex_f2(value);
puts_hex_f(value);
puts_hex_r(value);
return 0;
}