fork download
  1. #include <stdio.h>
  2. #define loctype long
  3. //#define loctype short
  4. //#define loctype double
  5. //#define loctype float
  6. #define value 3735928559 //a fun value which turns into DEADBEEF in hex.
  7. #define EOL 13
  8.  
  9. //Normally, of course, you would just printf in hex format:
  10. // printf("%04X", value); //replace 04 with sizeof(value)
  11. //But printf is ungodly huge and slow. If you need something tiny and faster...
  12.  
  13.  
  14. char hexnibblea (unsigned char b) {
  15. if (b>9) b+=('A'-10); else b+='0';
  16. return b;
  17. }
  18. /* A good C compiler should generate something like
  19.  
  20.  LOAD b
  21.  SUB #9
  22.  LOAD #55 ; 'A'-10
  23.  SKIP ABOVEZERO
  24.  LOAD #48 ; '0'
  25.  ADD b
  26.  SAVE b
  27.  
  28.  You don't want to know what they really generate. *facepalm*
  29. */
  30.  
  31. //if you don't mind wasting some program memory:
  32. #define hexnibble_m(b) "0123456789ABCDEF"[b]
  33. // or if you will use it more than once:
  34. char hexnibble (unsigned char b) {
  35. return hexnibble_m(b);
  36. }
  37.  
  38. void puts_hex_r(loctype h) { //type* & order agnostic, lsb first output
  39. char i;
  40. for (i = sizeof(loctype)*2-1; i>=0; i--) { //down count is faster
  41. putchar(hexnibble((unsigned char)h&0xF));
  42. h/=16; // easily optimized by most compilers
  43. }
  44. putchar(EOL);
  45. }
  46.  
  47. //the only problem with the above is that it is lsb first. And, as Aram notes:
  48. //"a byte (8 bit value), does not have endianness so you do not reverse the nibbles.
  49. // The correct output should be EFBEADDE00000000."
  50. //Since our goal here is just to move data over an ASCII channel, we can ignore
  51. //the byte order reversal.
  52.  
  53. //If you want msb first, and you have memory for a buffer:
  54. //https://stackoverflow.com/a/36968534/663416
  55. //otherwise...
  56. //Note: the following code is horrific. pointers, order dependant, fails for floats.
  57. void puts_hex_f(loctype h) {
  58. char i;
  59. unsigned char n;
  60. unsigned char *p = (unsigned char *)&h+sizeof(loctype)-1;
  61. for (i = sizeof(loctype)-1; i>=0; i--) {
  62. n = p[0];
  63. putchar(hexnibble(n>>4&0xF));
  64. putchar(hexnibble(n&0xF));
  65. p--;
  66. }
  67. putchar(EOL);
  68. }
  69.  
  70.  
  71. //slightly better is doing a union to join a byte array to the value
  72. //Note: the following code is horrific. wastes memory, order dependant, no floats.
  73. void puts_hex_f2(loctype h2) {
  74. union {
  75. loctype val;
  76. unsigned char b[sizeof(loctype)];
  77. } h;
  78. h.val=h2;
  79. char i;
  80. for (i=sizeof(loctype)-1;i>=0;i--) {
  81. putchar(hexnibble(h.b[i]>>4&0xF));
  82. putchar(hexnibble(h.b[i]&0xF));
  83. }
  84. putchar(EOL);
  85. }
  86. //That isn't bad if you want to show the internal representation of a value...
  87. //and again, if you have a buffer, life is grand
  88.  
  89.  
  90. void puts_hex_b(loctype h) {
  91. char buf[sizeof(loctype)*2+1];
  92. char i;
  93. buf[sizeof(loctype)*2+1]=0; //need a trailing zero to output via puts Thanks Aram!
  94. for (i = sizeof(loctype)*2-1; i>=0; i--) { //down count is faster
  95. buf[i] = hexnibble((unsigned char)h&0xF);
  96. h/=16; // easily optimized by most compilers
  97. }
  98. puts(buf);
  99. }
  100.  
  101. int main(void) {
  102. puts_hex_b(value);
  103. puts_hex_f2(value);
  104. puts_hex_f(value);
  105. puts_hex_r(value);
  106. printf("%04X", value);
  107. putchar(EOL);
  108.  
  109. putchar(hexnibble(0));
  110. putchar(hexnibble(1));
  111. putchar(hexnibble(2));
  112. putchar(hexnibble(3));
  113. putchar(hexnibble(4));
  114. putchar(hexnibble(5));
  115. putchar(hexnibble(6));
  116. putchar(hexnibble(7));
  117. putchar(hexnibble(8));
  118. putchar(hexnibble(9));
  119. putchar(hexnibble(10));
  120. putchar(hexnibble(11));
  121. putchar(hexnibble(12));
  122. putchar(hexnibble(13));
  123. putchar(hexnibble(14));
  124. putchar(hexnibble(15));
  125.  
  126.  
  127.  
  128. return 0;
  129. }
  130.  
Success #stdin #stdout 0s 4548KB
stdin
Standard input is empty
stdout
00000000DEADBEEF�
00000000DEADBEEF
00000000DEADBEEF
FEEBDAED00000000
DEADBEEF
0123456789ABCDEF