Adding 2 binary strings - c

I'm passing almost all leetCode tests with this, but not understanding why the output is wrong ("/0") when the input is:
a = "10100000100100110110010000010101111011011001101110111111111101000000101111001110001111100001101"
b = "110101001011101110001111100110001010100001101011101010000011011011001011101111001100000011011110011"
Anyone has an idea to what is not working ?
Thanks
#include <stdio.h>
#include <stdlib.h>
char * sumBinary(long int binary1, long int binary2, char * result);
char * addBinary(char * a, char * b)
{
char * result;
long int a_int;
long int b_int;
a_int = atoi(a);
b_int = atoi(b);
result = malloc(sizeof(*result) * 1000);
if (!result)
return (NULL);
sumBinary(a_int, b_int, result);
return (result);
}
char * sumBinary(long int binary1, long int binary2, char * result)
{
int i;
int t;
int rem;
int sum[1000];
i = 0;
t = 0;
rem = 0;
if ((binary1 == 0) && (binary2 == 0))
{
result[0] = '0';
result[1] = '\0';
}
else
{
while (binary1 != 0 || binary2 != 0)
{
sum[i++] = (binary1 %10 + binary2 % 10 + rem) % 2;
rem = (binary1 %10 + binary2 % 10 + rem) / 2;
binary1 = binary1 / 10;
binary2 = binary2 / 10;
}
if (rem != 0)
sum[i++] = rem;
--i;
while (i >= 0)
{
result[t] = sum[i] + '0';
t++;
i--;
}
result[t] = '\0';
}
return (result);
}

For a start, you should be using atol(3), not atoi(3) if you're using long int. But that's not the main issue here.
atol(3) and atoi(3) expect strings containing decimal numbers, not binary, so that's not going to work well for you. You would need strtol(3), which you can tell to expect a string in ASCII binary. But again, this is not the main issue.
You don't give the question text, but I'm guessing they want you to add two arbitrarily-long ASCII-binary strings, resulting in an ASCII-binary string.
I imagine their expectation, given it's arbitrarily-long, is that you would be working entirely in the string domain. So you'd allocate for a string whose length is two greater than the longer of the two you get as parameters (+1 for the terminal NUL, the other +1 for a potential overflow digit).
Then you start from the end, working back to the start, adding the corresponding digits of the parameter strings, placing the results into the result string starting from its end (allowing for that terminal NUL), adding as if you were doing it by hand.
Don't forget to add a leading zero to the result string, if you don't overflow into that position.
Note that I'm not going to write the code for you. This is either a learning exercise or a test: either way, you need to do the coding so you can learn from it.

Related

How output a numbers with write() (only #include <unistd.h> allowed) [duplicate]

It is possible to convert integer to string in C without sprintf?
There's a nonstandard function:
char *string = itoa(numberToConvert, 10); // assuming you want a base-10 representation
Edit: it seems you want some algorithm to do this. Here's how in base-10:
#include <stdio.h>
#define STRINGIFY(x) #x
#define INTMIN_STR STRINGIFY(INT_MIN)
int main() {
int anInteger = -13765; // or whatever
if (anInteger == INT_MIN) { // handle corner case
puts(INTMIN_STR);
return 0;
}
int flag = 0;
char str[128] = { 0 }; // large enough for an int even on 64-bit
int i = 126;
if (anInteger < 0) {
flag = 1;
anInteger = -anInteger;
}
while (anInteger != 0) { 
str[i--] = (anInteger % 10) + '0';
anInteger /= 10;
}
if (flag) str[i--] = '-';
printf("The number was: %s\n", str + i + 1);
return 0;
}
Here's an example of how it might work. Given a buffer and a size, we'll keep dividing by 10 and fill the buffer with digits. We'll return -1 if there is not enough space in the buffer.
int
integer_to_string(char *buf, size_t bufsize, int n)
{
char *start;
// Handle negative numbers.
//
if (n < 0)
{
if (!bufsize)
return -1;
*buf++ = '-';
bufsize--;
}
// Remember the start of the string... This will come into play
// at the end.
//
start = buf;
do
{
// Handle the current digit.
//
int digit;
if (!bufsize)
return -1;
digit = n % 10;
if (digit < 0)
digit *= -1;
*buf++ = digit + '0';
bufsize--;
n /= 10;
} while (n);
// Terminate the string.
//
if (!bufsize)
return -1;
*buf = 0;
// We wrote the string backwards, i.e. with least significant digits first.
// Now reverse the string.
//
--buf;
while (start < buf)
{
char a = *start;
*start = *buf;
*buf = a;
++start;
--buf;
}
return 0;
}
Unfortunately none of the answers above can really work out in a clean way in a situation where you need to concoct a string of alphanumeric characters.There are really weird cases I've seen, especially in interviews and at work.
The only bad part of the code is that you need to know the bounds of the integer so you can allocate "string" properly.
In spite of C being hailed predictable, it can have weird behaviour in a large system if you get lost in the coding.
The solution below returns a string of the integer representation with a null terminating character. This does not rely on any outer functions and works on negative integers as well!!
#include <stdio.h>
#include <stdlib.h>
void IntegertoString(char * string, int number) {
if(number == 0) { string[0] = '0'; return; };
int divide = 0;
int modResult;
int length = 0;
int isNegative = 0;
int copyOfNumber;
int offset = 0;
copyOfNumber = number;
if( number < 0 ) {
isNegative = 1;
number = 0 - number;
length++;
}
while(copyOfNumber != 0)
{
length++;
copyOfNumber /= 10;
}
for(divide = 0; divide < length; divide++) {
modResult = number % 10;
number = number / 10;
string[length - (divide + 1)] = modResult + '0';
}
if(isNegative) {
string[0] = '-';
}
string[length] = '\0';
}
int main(void) {
char string[10];
int number = -131230;
IntegertoString(string, number);
printf("%s\n", string);
return 0;
}
You can use itoa where available. If it is not available on your platform, the following implementation may be of interest:
https://web.archive.org/web/20130722203238/https://www.student.cs.uwaterloo.ca/~cs350/common/os161-src-html/atoi_8c-source.html
Usage:
char *numberAsString = itoa(integerValue);
UPDATE
Based on the R..'s comments, it may be worth modifying an existing itoa implementation to accept a result buffer from the caller, rather than having itoa allocate and return a buffer.
Such an implementation should accept both a buffer and the length of the buffer, taking care not to write past the end of the caller-provided buffer.
int i = 24344; /*integer*/
char *str = itoa(i);
/*allocates required memory and
then converts integer to string and the address of first byte of memory is returned to str pointer.*/

Why does my C array remember old data from a previous function call?

When I run the following C code I get the values:
222222222
312222222
102222222
I was expecting the values:
222222222
31
10
Why does the char number[] defined in my intToStr function remember previous values? I thought once the function call ended all local data was more or less destroyed.
#include <stdio.h>
void intToStr(int n);
int main(void)
{
intToStr(222222222);
intToStr(31);
intToStr(10);
return 0;
}
void intToStr(int n)
{
char number[10];
int l = 0;
if (n < 0)
{
l++;
number[0] = '-';
n *= -1;
}
int nCopy = n;
while (nCopy > 9)
{
nCopy /= 10;
l++;
}
int r;
while (n > 9)
{
r = n % 10;
n /= 10;
number[l--] = r + '0';
}
number[l] = n + '0';
printf("%s\n", number);
}
the array should not remember the old data
For each program, the C standard either:
specifies what the program should do
says that it is not specified what the program should do
It hardly ever says that the program should not do something in particular.
In this case, the standard says that it is not specified what characters should be in the array at the start of the function. They can be anything at all. Characters from the previous call is one particular case of "anything at all".
That's undefined behavior. If only the first 3 character are set, it may print 312222222 or it may print 312???????????????????
The last characters in char number[10] are not initialized, that means the compiler may decide to leave it alone and the old values stay, or something else happens.
Otherwise printf doesn't know where the string end, it keeps printing until it randomly hits a zero.
If there is buffer overrun printf finds a different set of characters in memory (which we are not supposed to be accessing) and the program keeps printing those same characters until it randomly hits a zero and finally stops.
To fix it, simply make sure there is '\0' at the end. You can also add additional check to make sure the length does not exceed the buffer size
Working example:
char number[10];
int l = 0;
if (n < 0)
{
l++;
number[0] = '-';
n *= -1;
}
if (n < 0) return;
int nCopy = n;
while (nCopy > 9)
{
nCopy /= 10;
l++;
}
int len = l;
if (len + 1 > sizeof(number))
return;
number[len + 1] = '\0';
int r;
while (n > 9)
{
r = n % 10;
n /= 10;
number[l--] = r + '0';
}
number[l] = n + '0';
printf("%s\n", number);

Multiplying large numbers through strings

I'm trying to write a program that will receive 2 strings representing numbers of any length
(for instance, char *a = "10000000000000";, char *b = "9999999999999999";) and multiply them.
This is what I came up with so far, not sure how to continue (nullify simply fills the whole string with '0'):
char *multiply(char *hnum, const char *other)
{
int num1=0, num2=0, carry=0, hnumL=0, otherL=0, i=0, temp1L=0, temp2L=0, n=0;
char *temp1, *temp2;
if(!hnum || !other) return NULL;
for(hnumL=0; hnum[hnumL] != '\0'; hnumL++);
for(otherL=0; other[otherL] != '\0'; otherL++);
temp1 = (char*)malloc(otherL+hnumL);
if(!temp1) return NULL;
temp2 = (char*)malloc(otherL+hnumL);
if(!temp2) return NULL;
nullify(temp1);
nullify(temp2);
hnumL--;
otherL--;
for(otherL; otherL >= 0; otherL--)
{
carry = 0;
num1 = other[otherL] - '0';
for(hnumL; hnumL >= 0; hnumL--)
{
num2 = hnum[hnumL] - '0';
temp1[i+n] = (char)(((int)'0') + ((num1 * num2 + carry) % 10));
carry = (num1 * num2 + carry) / 10;
i++;
temp1L++;
}
if(carry > 0)
{
temp1[i+n] = (char)(((int)'0') + carry);
temp1L++;
}
p.s. Is there a library that handles this already? Couldn't find anything like it.
On paper, you would probably do as follows:
999x99
--------
8991
8991
========
98901
The process is to multiply individual digits starting from the right of each number and adding them up keeping a carry in mind each time ("9 times 9 equals 81, write 1, keep 8 in mind"). I'm pretty sure you covered that in elementary school, didn't you?.
The process can be easily put into an algorithm:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct result
{
int carry;
int res;
};
/*
* multiply two numbers between 0 and 9 into result.res. If there is a carry, put it into
* result.carry
*/
struct result mul(int a, int b)
{
struct result res;
res.res = a * b;
if (res.res > 9)
{
res.carry = res.res / 10;
res.res %= 10;
}
else
res.carry = 0;
return res;
}
/*
* add
* adds a digit (b) to str at pos. If the result generates a carry,
* it's added also (recursively)
*/
add(char str[], int pos, int b)
{
int res;
int carry;
res = str[pos] - '0' + b;
if (res > 9)
{
carry = res / 10;
res %= 10;
add(str, pos - 1, carry);
}
str[pos] = res + '0';
}
void nullify(char *numstr, int len)
{
while (--len >= 0)
numstr[len] = '0';
}
int main(void)
{
struct result res;
char *mp1 = "999";
char *mp2 = "999";
char sum[strlen(mp1) + strlen(mp2) + 1];
int i;
int j;
nullify(sum, strlen(mp1) + strlen(mp2));
for (i = strlen(mp2) - 1; i >= 0; i--)
{
/* iterate from right over second multiplikand */
for (j = strlen(mp1) - 1; j >= 0; j--)
{
/* iterate from right over first multiplikand */
res = mul((mp2[i] - '0'), (mp1[j] - '0'));
add(sum, i + j + 1, res.res); /* add sum */
add(sum, i + j, res.carry); /* add carry */
}
}
printf("%s * %s = %s\n", mp1, mp2, sum);
return 0;
}
This is just the same as on paper, except that you don't need to remember individual summands since we add up everything on the fly.
This might not bee the fastest way to do it, but it doesn't need malloc() (provided you have a C99 compiler, otherwise you would need to dynamically allocate sum) and works for arbitrarily long numbers (up to the stack limit since add() is implemented as recursive function).
Yes there are libraries that handle this. It's actually a pretty big subject area that a lot of research has gone into. I haven't looked through your code that closely, but I know that the library implementations of big num operations have very efficient algorithms that you're unlikely to discover on your own. FOr example, the multiplication routine we all learned in grade school (pre common-core) is a O(n^2) solution to multiplication, but there exist ways to solve it in ~O(n^1.5).
THe standard GNU c big num library is GNU MP
https://gmplib.org/

Decimal to Binary conversion not working

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int myatoi(const char* string) {
int i = 0;
while (*string) {
i = (i << 3) + (i<<1) + (*string -'0');
string++;
}
return i;
}
void decimal2binary(char *decimal, int *binary) {
decimal = malloc(sizeof(char) * 32);
long int dec = myatoi(decimal);
long int fraction;
long int remainder;
long int factor = 1;
long int fractionfactor = .1;
long int wholenum;
long int bin;
long int onechecker;
wholenum = (int) dec;
fraction = dec - wholenum;
while (wholenum != 0 ) {
remainder = wholenum % 2; // get remainder
bin = bin + remainder * factor; // store the binary as you get remainder
wholenum /= 2; // divide by 2
factor *= 10; // times by 10 so it goes to the next digit
}
long int binaryfrac = 0;
int i;
for (i = 0; i < 10; i++) {
fraction *= 2; // times by two first
onechecker = fraction; // onechecker is for checking if greater than one
binaryfrac += fractionfactor * onechecker; // store into binary as you go
if (onechecker == 1) {
fraction -= onechecker; // if greater than 1 subtract the 1
}
fractionfactor /= 10;
}
bin += binaryfrac;
*binary = bin;
free(decimal);
}
int main(int argc, char **argv) {
char *data;
data = malloc(sizeof(char) * 32);
int datai = 1;
if (argc != 4) {
printf("invalid number of arguments\n");
return 1;
}
if (strcmp(argv[1], "-d")) {
if (strcmp(argv[3], "-b")) {
decimal2binary(argv[2], &datai);
printf("output is : %d" , datai);
} else {
printf("invalid parameter");
}
} else {
printf("invalid parameter");
}
free(data);
return 0;
}
In this problem, myatoi works fine and the decimal2binary algorithm is correct, but every time I run the code it gives my output as 0. I do not know why. Is it a problem with pointers? I already set the address of variable data but the output still doesn't change.
./dec2bin "-d" "23" "-b"
The line:
long int fractionfactor = .1;
will set fractionfactor to 0 because the variable is defined as an integer. Try using a float or double instead.
Similarly,
long int dec = myatoi(decimal);
stores an integer value, so wholenum is unnecessary.
Instead of
i = (i << 3) + (i<<1) + (*string -'0');
the code will be much more readable as
i = i * 10 + (*string - '0');
and, with today's optimizing compilers, both versions will likely generate the same object code. In general, especially when your code isn't working, favor readability over optimization.
fraction *= 2; // times by two first
Comments like this, that simply translate code to English, are unnecessary unless you're using the language in an unusual way. You can assume the reader is familiar with the language; it's far more helpful to explain your reasoning instead.
Another coding tip: instead of writing
if (strcmp(argv[1], "-d")) {
if (strcmp(argv[3], "-b")) {
decimal2binary(argv[2], &datai);
printf("output is : %d" , datai);
} else {
printf("invalid parameter");
}
} else {
printf("invalid parameter");
}
you can refactor the nested if blocks to make them simpler and easier to understand. In general it's a good idea to check for error conditions early, to separate the error-checking from the core processing, and to explain errors as specifically as possible so the user will know how to correct them.
If you do this, it may also be easier to realize that both of the original conditions should be negated:
if (strcmp(argv[1], "-d") != 0) {
printf("Error: first parameter must be -d\n");
else if (strcmp(argv[3], "-b") != 0) {
printf("Error: third parameter must be -b\n");
} else {
decimal2binary(argv[2], &datai);
printf("Output is: %d\n" , datai);
}
void decimal2binary(char *decimal, int *binary) {
decimal = malloc(sizeof(char) * 32);
...
}
The above lines of code allocate a new block of memory to decimal, which will then no longer point to the input data. Then the line
long int dec = myatoi(decimal);
assigns the (random values in the) newly-allocated memory to dec.
So remove the line
decimal = malloc(sizeof(char) * 32);
and you will get the correct answer.
if(!strcmp(argv[3] , "-b"))
if(!strcmp(argv[3] , "-d"))
The result of the string compare function should be negated so that you can proceed. Else it will print invalid parameter. Because the strcmp returns '0' when the string is equal.
In the 'decimal2binary' function you are allocating a new memory block inside the function for the input parameter 'decimal',
decimal = malloc(sizeof(char) * 32);
This would actually overwrite your input parameter data.

How to convert an arbitrary large integer from base 10 to base 16?

The program requires an input of an arbitrary large unsigned integer which is expressed as one string in base 10. The outputs is another string that expresses the integer in base 16.
For example, the input is "1234567890987654321234567890987654321234567890987654321",
and the output shall be "CE3B5A137DD015278E09864703E4FF9952FF6B62C1CB1"
The faster the algorithm the better.
It will be very easy if the input is limited within 32-bit or 64-bit integer; for example, the following code can do the conversion:
#define MAX_BUFFER 16
char hex[] = "0123456789ABCDEF";
char* dec2hex(unsigned input) {
char buff[MAX_BUFFER];
int i = 0, j = 0;
char* output;
if (input == 0) {
buff[0] = hex[0];
i = 1;
} else {
while (input) {
buff[i++] = hex[input % 16];
input = input / 16;
}
}
output = malloc((i + 1) * sizeof(char));
if (!output)
return NULL;
while (i > 0) {
output[j++] = buff[--i];
}
output[j] = '\0';
return output;
}
The real challenging part is the "arbitrary large" unsigned integer. I have googled but most of them are talking about the conversion within 32-bit or 64-bit. No luck is found.
Can anyone give any hit or any link that can be read on?
Thanks in advance.
Edit This is an interview question I encountered recently. Can anyone briefly explain how to solve this problem? I know there is a gmp library and I utilized it before; however as an interview question it requires not using external library.
Allocate an array of integers, number of elements is equal to the length of the input string. Initialize the array to all 0s.
This array of integers will store values in base 16.
Add the decimal digits from the input string to the end of the array. Mulitply existing values by 10 add carryover, store new value in array, new carryover value is newvalue div 16.
carryover = digit;
for (i = (nElements-1); i >= 0; i--)
{
newVal = array[index] * 10) + carryover;
array[index] = newval % 16;
carryover = newval / 16;
}
print array, start at 0th entry and skip leading 0s.
Here's some code that will work. No doubt there are probably a few optimizations that could be made. But this should suffice as a quick and dirty solution:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "sys/types.h"
char HexChar [16] = { '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
static int * initHexArray (char * pDecStr, int * pnElements);
static void addDecValue (int * pMyArray, int nElements, int value);
static void printHexArray (int * pHexArray, int nElements);
static void
addDecValue (int * pHexArray, int nElements, int value)
{
int carryover = value;
int tmp = 0;
int i;
/* start at the bottom of the array and work towards the top
*
* multiply the existing array value by 10, then add new value.
* carry over remainder as you work back towards the top of the array
*/
for (i = (nElements-1); (i >= 0); i--)
{
tmp = (pHexArray[i] * 10) + carryover;
pHexArray[i] = tmp % 16;
carryover = tmp / 16;
}
}
static int *
initHexArray (char * pDecStr, int * pnElements)
{
int * pArray = NULL;
int lenDecStr = strlen (pDecStr);
int i;
/* allocate an array of integer values to store intermediate results
* only need as many as the input string as going from base 10 to
* base 16 will never result in a larger number of digits, but for values
* less than "16" will use the same number
*/
pArray = (int *) calloc (lenDecStr, sizeof (int));
for (i = 0; i < lenDecStr; i++)
{
addDecValue (pArray, lenDecStr, pDecStr[i] - '0');
}
*pnElements = lenDecStr;
return (pArray);
}
static void
printHexArray (int * pHexArray, int nElements)
{
int start = 0;
int i;
/* skip all the leading 0s */
while ((pHexArray[start] == 0) && (start < (nElements-1)))
{
start++;
}
for (i = start; i < nElements; i++)
{
printf ("%c", HexChar[pHexArray[i]]);
}
printf ("\n");
}
int
main (int argc, char * argv[])
{
int i;
int * pMyArray = NULL;
int nElements;
if (argc < 2)
{
printf ("Usage: %s decimalString\n", argv[0]);
return (-1);
}
pMyArray = initHexArray (argv[1], &nElements);
printHexArray (pMyArray, nElements);
if (pMyArray != NULL)
free (pMyArray);
return (0);
}
I have written an article which describes a simple solution in Python which can be used to transfrom a series of numbers from and to arbitrary number bases. I've originally implemented the solution in C, and I didn't want a dependency to an external library. I think you should be able to rewrite the very easy Python code in C or whatever you like.
Here is the Python code:
import math
import string
def incNumberByValue(digits, base, value):
# The initial overflow is the 'value' to add to the number.
overflow = value
# Traverse list of digits in reverse order.
for i in reversed(xrange(len(digits))):
# If there is no overflow we can stop overflow propagation to next higher digit(s).
if not overflow:
return
sum = digits[i] + overflow
digits[i] = sum % base
overflow = sum / base
def multNumberByValue(digits, base, value):
overflow = 0
# Traverse list of digits in reverse order.
for i in reversed(xrange(len(digits))):
tmp = (digits[i] * value) + overflow
digits[i] = tmp % base
overflow = tmp / base
def convertNumber(srcDigits, srcBase, destDigits, destBase):
for srcDigit in srcDigits:
multNumberByValue(destDigits, destBase, srcBase)
incNumberByValue(destDigits, destBase, srcDigit)
def withoutLeadingZeros(digits):
for i in xrange(len(digits)):
if digits[i] != 0:
break
return digits[i:]
def convertNumberExt(srcDigits, srcBase, destBase):
# Generate a list of zero's which is long enough to hold the destination number.
destDigits = [0] * int(math.ceil(len(srcDigits)*math.log(srcBase)/math.log(destBase)))
# Do conversion.
convertNumber(srcDigits, srcBase, destDigits, destBase)
# Return result (without leading zeros).
return withoutLeadingZeros(destDigits)
# Example: Convert base 10 to base 16
base10 = [int(c) for c in '1234567890987654321234567890987654321234567890987654321']
base16 = convertNumberExt(base10, 10, 16)
# Output list of base 16 digits as HEX string.
hexDigits = '0123456789ABCDEF'
string.join((hexDigits[n] for n in base16), '')
The real challenging part is the "arbitrary large" unsigned integer.
Have you tried using GNU MP Bignum library?
Unix dc is able to do base conversions on arbitrary large integers. Open BSD source code is available here.
Here's a BigInt library:
http://www.codeproject.com/KB/cs/BigInt.aspx?msg=3038072#xx3038072xx
No idea if it works, but it's the first one I found with Google. It appears to have functions to parse and format big integers, so they may support different bases too.
Edit: Ahh, you're using C, my mistake. But you may be able to pick up ideas from the code, or someone using .NET may have the same question, so I'll leave this here.
You can try this arbitrary length input C99 base_convert (between 2 and 62) function :
#include <stdlib.h>
#include <string.h>
static char *base_convert(const char * str, const int base_in, const int base_out) {
static const char *alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
size_t a, b, c = 1, d;
char *s = malloc(c + 1);
strcpy(s, "0");
for (; *str; ++str) {
for (a = (char*)memchr(alphabet, *str, base_out) - alphabet, b = c; b;) {
d = ((char *) memchr(alphabet, s[--b], base_out) - alphabet) * base_in + a;
s[b] = alphabet[d % base_out];
a = d / base_out;
}
for (; a; s = realloc(s, ++c + 1), memmove(s + 1, s, c), *s = alphabet[a % base_out], a /= base_out);
}
return s;
}
Try it Online - Example usage :
#include <stdio.h>
int main() {
char * res = base_convert("12345678909876543212345678909876"
"54321234567890987654321", 10, 16);
puts(res);
free(res);
// print CE3B5A137DD015278E09864703E4FF9952FF6B62C1CB1
}
Example output :
'11100100100011101011001001110110001101001001100010100001111011110011000010'
from base 2 to base 58 is 'BaseConvert62'.
'NdN2mbALtnCHH' from base 60 to base 59 is 'StackOverflow'.
Tested with your example and Fibonacci(1500000).
Thank You.
Python:
>>> from string import upper
>>> input = "1234567890987654321234567890987654321234567890987654321"
>>> output = upper(hex(int(input)))[2:-1]
>>> print output
CE3B5A137DD015278E09864703E4FF9952FF6B62C1CB1
Here is the above-mentioned algorithm implemented in javascript:
function addDecValue(hexArray, value) {
let carryover = value;
for (let i = (hexArray.length - 1); i >= 0; i--) {
let rawDigit = ((hexArray[i] || 0) * 10) + carryover;
hexArray[i] = rawDigit % 16;
carryover = Math.floor(rawDigit / 16);
}
}
function toHexArray(decimalString) {
let hexArray = new Array(decimalString.length);
for (let i = 0; i < decimalString.length; i++) {
addDecValue(hexArray, Number(decimalString.charAt(i)));
}
return hexArray;
}
function toHexString(hexArray) {
const hexDigits = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'];
let result = '';
for (let i = 0; i < hexArray.length; i++) {
if (result === '' && hexArray[i] === 0) continue;
result += hexDigits[hexArray[i]];
}
return result
}
toHexString(toHexArray('1234567890987654321234567890987654321234567890987654321'));

Resources