#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
		}
	putchar(EOL);
	}

//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];
		putchar(hexnibble(n>>4&0xF));
		putchar(hexnibble(n&0xF));
		p--;
		}
	putchar(EOL);
	}


//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--) {
		putchar(hexnibble(h.b[i]>>4&0xF));
		putchar(hexnibble(h.b[i]&0xF));
		}
	putchar(EOL);
	}
//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
		}
	puts(buf);
	}

int main(void) {
	puts_hex_b(value);
	puts_hex_f2(value);
	puts_hex_f(value);
	puts_hex_r(value);
	printf("%04X", value); 
	putchar(EOL);
	
	putchar(hexnibble(0));
	putchar(hexnibble(1));
	putchar(hexnibble(2));
	putchar(hexnibble(3));
	putchar(hexnibble(4));
	putchar(hexnibble(5));
	putchar(hexnibble(6));
	putchar(hexnibble(7));
	putchar(hexnibble(8));
	putchar(hexnibble(9));
	putchar(hexnibble(10));
	putchar(hexnibble(11));
	putchar(hexnibble(12));
	putchar(hexnibble(13));
	putchar(hexnibble(14));
	putchar(hexnibble(15));
	
	
	
	return 0;
}
