You can trade some memory space for calculation time, if that is your concern, using a simple and small look-up table.
Consider this C++ (earlier versions of your question asked for ideas in that language too) snippet as an example of the algorithm I'm proposing.
#include <iostream>
#include <array>
#include <vector>
#include <string>
#include <iomanip>
#include <algorithm>
#include <limits>
std::string ternary_from(int value)
{
// The idea is to elaborate three figures (in base 3) at a time
constexpr int dim = 3 * 3 * 3;
// Note the values, are "reversed"
static const std::array<std::string, dim> inner_parts {
"000", "100", "200", "010", "110", "210", "020", "120", "220",
"001", "101", "201", "011", "111", "211", "021", "121", "221",
"002", "102", "202", "012", "112", "212", "022", "122", "222"
};
static const std::array<std::string, dim> parts {
"", "1", "2", "01", "11", "21", "02", "12", "22",
"001", "101", "201", "011", "111", "211", "021", "121", "221",
"002", "102", "202", "012", "112", "212", "022", "122", "222"
};
if ( value == 0 )
return std::string{"0"};
std::string result;
// Thanks @Chux for recalling that -INT_MIN is UB
unsigned tmp = value;
if ( value < 0 )
tmp = -tmp;
// note that 'dim' = 27, so you are performing a third of the calculations
while (tmp >= dim)
{
unsigned remainder = tmp % dim;
// concatenating a string at the end is easier...
result += inner_parts[remainder];
tmp = tmp / dim;
}
result += parts[tmp];
if (value < 0)
result += '-';
// now the string needs to be reversed. e.g. 3 -> 10(3), not 01
std::reverse(result.begin(), result.end());
return result;
}
int main()
{
std::vector<int> tests {
42, -8, 0, 81, 27, -28, std::numeric_limits<int>::max(), std::numeric_limits<int>::min()
};
std::cout << " decimal ternary\n";
for (int i : tests)
{
std::cout << std::setw(12) << i << std::setw(23) << ternary_from(i) << '\n';
}
}
It outputs
decimal ternary
42 1120
-8 -22
0 0
81 10000
27 1000
-28 -1001
2147483647 12112122212110202101
-2147483648 -12112122212110202102
charstrings in C are really called null-terminated byte strings. That null-terminated bit is important, and means that a string of three characters needs space for four to include the terminator. The second problem is related to the previous, in that you don't terminate the string. The third problem is that you return a pointer to the first element ofbuffer, and once the function returnsbuffergoes out of scope and practically cease to exist, leaving you with a stray and invalid pointer - Some programmer dude