Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I would like to print superscript and subscript with printf, like x¹?

I want to print out a polynomial expression in c but i don't know print x to the power of a number with printf

like image 276
Ruchdane AMADOU Avatar asked Sep 05 '25 03:09

Ruchdane AMADOU


1 Answers

It's far from trivial unfortunately. You cannot achieve what you want with printf. You need wprintf. Furthermore, it's not trivial to translate between normal and superscript. You would like a function like this:

wchar_t digit_to_superscript(int d) {
    wchar_t table[] = { // Unicode values
        0x2070, 
        0x00B9,         // Note that 1, 2 and 3 does not follow the pattern
        0x00B2,         // That's because those three were common in various
        0x00B3,         // extended ascii tables. The rest did not exist
        0x2074,         // before unicode
        0x2075,
        0x2076,
        0x2077,
        0x2078,
        0x2079,
    };

    return table[d];
}
    

This function could of course be changed to handle other characters too, as long as they are supported. And you could also write more complete functions operating on complete strings.

But as I said, it's not trivial, and it cannot be done with simple format strings to printf, and not even to wprintf.

Here is a somewhat working example. It's usable, but it's very short because I have omitted all error checking and such. Shortest possible to be able to use a negative float number as exponent.

#include <wchar.h>
#include <locale.h>

wchar_t char_to_superscript(wchar_t c) {
    wchar_t digit_table[] = {
        0x2070, 0x00B9, 0x00B2, 0x00B3, 0x2074, 
        0x2075, 0x2076, 0x2077, 0x2078, 0x2079,
    };

    if(c >= '0' && c <= '9') return digit_table[c - '0'];
    switch(c) {
        case '.': return 0x22C5; 
        case '-': return 0x207B;
    }
}

void number_to_superscript(wchar_t *dest, wchar_t *src) {
    while(*src){
        *dest = char_to_superscript(*src);
        src++;
        dest++;
    }
    dest++;
    *dest = 0;
}

And a main function to demonstrate:

int main(void) {
    setlocale(LC_CTYPE, "");
    double x = -3.5;
    wchar_t wstr[100], a[100];
    swprintf(a, 100, L"%f", x);
    wprintf(L"Number as a string: %ls\n", a);
    number_to_superscript(wstr, a);
    wprintf(L"Number as exponent: x%ls\n", wstr);
}

Output:

Number as a string: -3.500000
Number as exponent: x⁻³⋅⁵⁰⁰⁰⁰⁰

In order to make a complete translator, you would need something like this:

size_t superscript_index(wchar_t c) {
    // Code
}

wchar_t to_superscript(wchar_t c) {
    static wchar_t huge_table[] {
         // Long list of values
    };

    return huge_table[superscript_index(c)];
}

Remember that this cannot be done for all characters. Only those whose counterpart exists as a superscript version.

like image 86
klutt Avatar answered Sep 08 '25 01:09

klutt