Computing: Free Pascal Programming

Display of number subscripts and superscripts.

If you write some mathematics, physics, or chemistry program, it often happens that you need to display number subscripts or superscripts. Examples:

It's, of course, possible to display these items without using subscripts/superscripts. In the case of a subscript, we can just display a "regular" number. Examples: x = x0 + vt; H2SO4. In the case of a superscript, we can use the caret (^) symbol. Examples: x = 0.5at^2; Ca^2+ or Ca^(2+). But, isn't it lots nicer to display the item as it would be in a textbook, and display the subscripts and superscripts as such?

The digits 0 to 9, as well as the "+" and "-" symbols may be easily displayed as subscripts/superscripts, using their UTF-8 code expressed as a sequence of character values (ASCII code, preceded by the "#" symbol). This works not only correctly in a GUI application, but also in a Windows command line program, provided that the code page of Windows Command Prompt is set to the pseudo-UTF-8 code page 65001 (cf. my tutorial Creating command line programs with Lazarus). As the displayed items are ASCII sequences, it is not necessary to include the LazUTF8 unit (thus, not necessary to add the LazUtils package as project requirement).

Here is a list of the 9 digits character values to be used as subscripts:

0#$E2#$82#$80
1#$E2#$82#$81
2#$E2#$82#$82
3#$E2#$82#$83
4#$E2#$82#$84
5#$E2#$82#$85
6#$E2#$82#$86
7#$E2#$82#$87
8#$E2#$82#$88
9#$E2#$82#$89

And here is a list of the 9 digits and "+" and "-" symbols character values to be used as superscripts:

0#$E2#$81#$B0
1#$C2#$B9
2#$C2#$B2
3#$C2#$B3
4#$E2#$81#$B4
5#$E2#$81#$B5
6#$E2#$81#$B6
7#$E2#$81#$B7
8#$E2#$81#$B8
9#$E2#$81#$B9
+#$E2#$81#$BA
-#$E2#$81#$BB

Example 1.

Let's consider a program that deals with second degree equations of the form ax2 + bx + c = 0. Let's the user enter the equation parameters, and then display the equation, with ax2 properly printed with superscript 2. The simplest way to do this, is to create an equation string with ax2 expressed as 'a^2', and then replace 'a^2' by 'a' + SUP_2, where SUP_2 is a constant set to #$C2#$B2. Here is the code:

    program ss1;
    uses
        SysUtils;
    const
        SUP_2 = #$C2#$B2;
    var
        Equation: string;
        A, B, C: Real;
    begin
        Writeln('Second degree equation in x.');
        Write('a = ? '); Readln(A);
        Write('b = ? '); Readln(B);
        Write('c = ? '); Readln(C);
        Equation := FloatToStr(A) + 'x^2';
        if B >= 0 then
            Equation += ' + '
        else
            Equation += ' - ';
        Equation += FloatToStr(Abs(B)) + 'x';
        if C >= 0 then
            Equation += ' + '
        else
            Equation += ' - ';
        Equation += FloatToStr(Abs(C)) + ' = 0';
        Equation := StringReplace(Equation, '^2', SUP_2, []);
        Writeln(Equation);
    end.

Note: The value entered for A is supposed to be different from 0. To really properly display the equation, code has to be added for the cases where B or C are 0 (the Bx, resp. C part removed from the equation string).

The screenshot shows an execution of the program.

Lazarus/Free Pascal: Math equations - Display of a superscript number

Example 2.

Let's consider a program, that asks the user for the chemical formula of a molecule, and then displays this formula properly, with the number of the different atoms as subscripts. In this case, we can define an array SUBS_Digits with the subscripts character values sequences as elements. We then iterate over the formula using a counter variable varying from 0 to 9, and replace all occurrences of the value of the counter variable by the corresponding element of the SUBS_Digits array. Here is the code:

    program ss2;
    uses
        SysUtils;
    const
        SUB_Digits: array[0..9] of string = (
            #$E2#$82#$80, #$E2#$82#$81, #$E2#$82#$82, #$E2#$82#$83, #$E2#$82#$84, #$E2#$82#$85, #$E2#$82#$86, #$E2#$82#$87, #$E2#$82#$88, #$E2#$82#$89
        );
    var
        I: Integer;
        Formula: string;
    begin
        Write('Enter chemical formula?  ');
        Readln(Formula);
        for I := 0 to 9 do
            Formula := StringReplace(Formula, IntToStr(I), SUB_Digits[I], [rfReplaceAll]);
        Writeln('Formula with subscripts: ', Formula);
    end.

Screenshot of a program execution.

Lazarus/Free Pascal: Molecule formulas - Display of subscript numbers

Example 3.

And to terminate the tutorial, let's consider a program, that displays the chemical formula of an ion in its proper form, i.e. the number of the different atoms as subscripts, and the ion charge as superscript. The way to proceed is similar as before. However, we have to make sure that the program understands if the last number before the "+" or "-" sign is the ion charge (as in Ca2+), or the number of atoms of the last atom in the formula (as in NH4+). One possibility would be to use the caret symbol as indicator for the ion charge. A simpler possibility (with a nicer display, also often used in textbooks) is to put the molecule between square brackets. Here is the code:

    program ss3;
    uses
        SysUtils;
    const
        SUP_PLUS = #$E2#$81#$BA; SUP_MINUS = #$E2#$81#$BB;
        SUP_Digits: array[0..9] of string = (
            #$E2#$81#$B0, #$C2#$B9, #$C2#$B2, #$C2#$B3, #$E2#$81#$B4, #$E2#$81#$B5, #$E2#$81#$B6, #$E2#$81#$B7, #$E2#$81#$B8, #$E2#$81#$B9
        );
        SUB_Digits: array[0..9] of string = (
            #$E2#$82#$80, #$E2#$82#$81, #$E2#$82#$82, #$E2#$82#$83, #$E2#$82#$84, #$E2#$82#$85, #$E2#$82#$86, #$E2#$82#$87, #$E2#$82#$88, #$E2#$82#$89
        );
    var
        I: Integer;
        Formula: string;
    begin
        repeat
            Write('Enter formula?  ');
            Readln(Formula);
            if Formula <> '' then begin
                Formula := StringReplace(Formula, '+', SUP_Plus, []);
                Formula := StringReplace(Formula, '-', SUP_Minus, []);
                for I := 0 to 9 do begin
                    Formula := StringReplace(Formula, IntToStr(I) + SUP_Plus, SUP_Digits[I] + SUP_Plus, []);
                    Formula := StringReplace(Formula, IntToStr(I) + SUP_Minus, SUP_Digits[I] + SUP_Minus, []);
                    Formula := StringReplace(Formula, IntToStr(I), SUB_Digits[I], [rfReplaceAll]);
                end;
                Writeln('Proper formula: ', Formula);
            end;
        until Formula = '';
    end.

First, we replace the "+" and "-" symbols by the corresponding superscript sequence; this is necessary for ions with a charge of +1 or -1 ("+" resp "-" symbol, not preceded by a number). Then we replace a number, followed by superscript "+" or "-", by the corresponding superscript sequence using the SUP_Digits array (charges being supposed to be less than 10). Finally, we replace all resting numbers (these actually are number of atoms) by the corresponding subscript sequence using the SUB_Digits array.

Screenshot of a program execution.

Lazarus/Free Pascal: Ion formulas - Display of subscript and superscripts numbers

If you find this text helpful, please, support me and this website by signing my guestbook.