109 lines
2.4 KiB
C++
109 lines
2.4 KiB
C++
/*
|
|
* Print a base10 number in base32
|
|
*
|
|
* Using a multiple of bits, arithmetic is done very fast
|
|
* since cpus talk bits, we can use bit operations which are faster
|
|
*+ than regular (base10) operations
|
|
*
|
|
* also, in base 2^k you can see the splitting on bits
|
|
* with k the amount of bits used to represent the character
|
|
* =>
|
|
* b2: "1100001010100101"
|
|
* b10: "49829"
|
|
* ==
|
|
* b2 per 4 bits: "1100 0010 1010 0101"
|
|
* b10: "12 2 10 5"
|
|
* b16: "C 2 A 5"
|
|
* ==
|
|
* b2 per 5 bits: "(0000)1 10000 10101 00101"
|
|
* b10: "1 16 21 5"
|
|
* b32: "1 G L 5"
|
|
*/
|
|
|
|
#include <iostream>
|
|
#include <cmath>
|
|
|
|
#define VERBOSE false
|
|
|
|
char b32_lookup_table[] = "ABCDEFGHIJKLMNOPQRSTUV";
|
|
int base = 8;
|
|
|
|
int main() {
|
|
//a
|
|
unsigned int number = 16384;
|
|
// get the input unsigned integer
|
|
std::cout << "Enter a Positive Integer: ";
|
|
std::cin >> number;
|
|
|
|
if ( VERBOSE ) {
|
|
std::cout << "Number " << number << std::endl;
|
|
std::cout << "Base " << base << std::endl;
|
|
}
|
|
|
|
//b
|
|
int bits_in_char = log(base)/log(2);// 5 = log2(32)
|
|
int bits_in_int = 8 * sizeof(int);// 32 bits
|
|
|
|
int chars_per_int = std::ceil(bits_in_int / bits_in_char);// 7 chars needed
|
|
|
|
if ( VERBOSE ) {
|
|
std::cout << "Chars per int = " << chars_per_int << " ( " << bits_in_int << " / " << bits_in_char << " ) " << std::endl;
|
|
}
|
|
|
|
//c
|
|
unsigned short digits[chars_per_int];
|
|
|
|
//d & e
|
|
short digit_num = 0;
|
|
short lsb_bitmask = ( 1 << bits_in_char ) - 1;// 00011111 = 0x1F
|
|
|
|
if ( VERBOSE ) {
|
|
std::cout << "Bitmask = 0x" << std::uppercase << std::hex << lsb_bitmask << std::dec << std::endl;
|
|
std::cout << std::endl;
|
|
}
|
|
|
|
// Loop until the remainder is 0
|
|
// I'm truncating all 0s in front of MSB
|
|
while ( number > 0 )
|
|
{
|
|
if ( VERBOSE ) {
|
|
std::cout << "Entering loop with number = " << number << std::endl;
|
|
std::cout << " - b16: 0x" << std::hex << number << std::dec << std::endl;
|
|
}
|
|
|
|
// Mask with the last 5 bits
|
|
digits[digit_num] = number & lsb_bitmask;
|
|
|
|
// Shift off the bits we have put in to the array
|
|
number = ( number >> bits_in_char );
|
|
|
|
++digit_num;
|
|
}
|
|
--digit_num;
|
|
|
|
if ( VERBOSE ) {
|
|
std::cout << "We have " << digit_num + 1 << " digits" << std::endl;
|
|
std::cout << std::endl;
|
|
}
|
|
|
|
|
|
//f
|
|
// Loop the other way so the first digit we get out is MSB
|
|
while ( digit_num >= 0 )
|
|
{
|
|
if ( digits[digit_num] < 10 )
|
|
{
|
|
std::cout << digits[digit_num];
|
|
}
|
|
else
|
|
{
|
|
std::cout << b32_lookup_table[digits[digit_num] - 10];
|
|
}
|
|
|
|
digit_num--;
|
|
}
|
|
|
|
std::cout << std::endl;
|
|
|
|
return 0;
|
|
}
|