Home > OS >  How to print values in reverse without the use of arrays nor pointers in C
How to print values in reverse without the use of arrays nor pointers in C

Time:10-23

I've been working on a code that converts a given number (decimal base) to any other base from 2 to 16.

Clearly, I've come across the issue that the function base_conversion_it (it stands for iterative) prints the values in reverse.

I cannot use arrays nor pointers, and everyone on the internet seems to solve this issue like that. My assignment requires making both an iterative and a recursive function (which I did and works).

void base_conversion_it(unsigned int n, unsigned int b) {

    if (n > 0) {

        //bases between 2 and 16
        if (b >= 2 && b <= 16) {

            int r;          //r = remainder
            int q = 1;      //quotient
            int num;        //saves the remainder

            while (q != 0) {

                r = n % b;
                printf("%X", r);

                q = n / b;
                n = q;
            }
        }
    }
}

CodePudding user response:

You start converting from the units digit.
Maybe start with the most significant digit instead?

// It's Undefined Behaviour if `b` is outside the range [2...16]
void base_conversion_it(unsigned int n, unsigned int b) {
    unsigned highestbase = 1;
    while (highestbase * b <= n) highestbase *= b; //possible wrap around and infinite loop

    while (highestbase) {
        printf("%X", n / highestbase);
        n %= highestbase;
        highestbase /= b;
    }
    printf("\n");
}

CodePudding user response:

Sorry missed iterative.

char digits[] = "0123456789ABCDEFGHIJKLMNOP";

void print(unsigned long long val, unsigned base)
{
    unsigned long long mask = base;
    while(val / mask >= base) mask *= base;
    do
    {
        printf("%c", digits[val / mask]);
        val %= mask;
        mask /= base;
    }while(val);
}

int main(void)
{
    print(45654756453, 10); printf("\n");
    print(45654756453, 16); printf("\n");
    print(45654756453, 24); printf("\n");
    print(45654756453, 2); printf("\n");
}

https://godbolt.org/z/W3fGnnhYs

Recursion:

char digits[] = "0123456789ABCDEF";

void print(unsigned long long val, unsigned base)
{
    if(base <= 16 && base > 1)
    {
        if(val >= base) print(val / base, base);
        printf("%c", digits[val % base]);
    }
}

https://godbolt.org/z/84hYocnjv

CodePudding user response:

If you cannot use either arrays (including strings) or recursion, then I think you need to compute the output digits in most-significant-first order. This is a bit less natural than computing them in the opposite order and reversing the result, but it can be done:

  • use a loop to find the place value of the most significant non-zero base-b digit of n. For example, check the result of dividing n by successive powers of b until the result is 0, then back off one step.

  • In a separate loop, read off the base-b digits of n one by one, starting with the one at the discovered most-significant position. For each digit,

    1. Divide the current value of n by the place value pv of the current digit to get a digit value.
    2. Replace n with n % pv.

    Be careful to continue all the way down to place value 1, as opposed, say, to stopping when n becomes zero.

  • Related