--- title: "Decimal Columns" id: 71186 type: "computer_media" slug: "decimal-columns" url: "http://localhost/computer_media/decimal-columns/" markdown_url: "http://localhost/computer_media/decimal-columns.md" published_at: "2026-08-30T22:50:06+00:00" modified_at: "2026-08-30T22:50:06+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/08/decimal-columns.png" alt: "Decimal Columns screen" excerpt: "A clever two-decimal-place formatter that right-aligns numbers across screen columns using DEF FN rounding and string-padding tricks." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" indiv: - name: "Algis Gedris" slug: "algis-gedris" taxonomy: "indiv" url: "http://localhost/indiv/algis-gedris/" genre: - name: "Programming" slug: "programming" taxonomy: "genre" url: "http://localhost/type/programming/" media_type: "Program" programmers: - name: "Algis Gedris" slug: "algis-gedris" taxonomy: "indiv" url: "http://localhost/indiv/algis-gedris/" download_url: "https://archive.org/download/timex-sinclair-software-archive/Decimal%20Columns%20%28198x%29%28Gedris%2C%20Algis%29%28TS2068%29%28US%29%28Program%29.zip" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2026/08/decimal-columns.png" alt: "Decimal Columns screen" media_type_tags: "Programming" --- # Decimal Columns Decimal Columns is a BASIC program that accepts a numeric input and prints it right-aligned across multiple screen columns, formatted to exactly two decimal places. The core formatting logic uses two DEF FN functions: one rounds a number to two decimal places using the INT(100*K+0.5)/100 technique, and a second constructs the display string by appending “.00” when the value is a whole number, or a trailing “0” when only one decimal digit is present. Lines 110–140, which divide and multiply the input to generate derived values for columns 2 and 3, are marked optional and can be removed for single-column output. The TAB positioning arithmetic (e.g., TAB 10-LEN K$) achieves right-alignment by subtracting the string length from the target column stop. *** ### Program Structure The program is organized into three functional blocks: setup and display (lines 10–90), the main input-and-print loop (lines 90–150), and the formatting subroutine with its supporting function definitions (lines 160–200). Lines 10–50 are entirely `REM` statements serving as documentation. Line 60 clears the screen and prints a header. The main loop at lines 90–150 accepts a number, formats and prints it up to three times, then loops back to `GO TO 90`. ### Column Layout Three columns are produced at TAB stops 10, 20, and 30. Right-alignment within each column is achieved by the expression `TAB 10-LEN K$` (and analogously for 20 and 30), so that the last character of the formatted string always lands on the column boundary. Lines 110–140, which compute derived values (K/3 and that result times 2) for columns 2 and 3, are flagged in the REMs as optional; removing them reduces the output to a single right-aligned column. ### Formatting Subroutine The subroutine at line 160 calls two DEF FN functions in sequence and returns the formatted string in `K$`: - `DEF FN K(K) = INT(100*K+0.5)/100` (line 170) — rounds the value to two decimal places using the classic multiply-round-divide idiom. The comment in line 190 correctly notes that changing 100 to 1000 would extend precision to three decimal places. - `DEF FN K$(K,K$) = K$+(".00" AND K=INT K)+("0" AND ("0"+K$)(LEN K$)=".")` (line 180) — appends the necessary suffix to the numeric string. The first term adds `.00` when the rounded value is a whole number. The second term appends a trailing `0` when the last character of `K$` is a decimal point, covering cases like “3.5” displayed as “3.50”. The string Boolean idiom (`"text" AND condition`) is standard Spectrum BASIC practice. ### Key BASIC Idioms - **Right-alignment via TAB arithmetic:**`PRINT TAB 10-LEN K$;K$;` is a concise one-expression right-align for a fixed column width. - **String Boolean padding:** Using `AND` with a string literal to conditionally concatenate text is a well-known Spectrum idiom that avoids IF/THEN branching. - **Trailing semicolon:** Each `PRINT` statement ends with `;` to suppress the newline, allowing all three column values to appear on the same line. - **Chained DEF FN calls:** The subroutine applies two sequential function calls, using the same variable name `K` as both the FN parameter and the main variable, which is valid in Spectrum BASIC but requires careful reading. ### Notable Anomalies and Observations Line 90 reads `INPUT "ENTER A NUMBER: ";k` (lowercase `k`), which is the same variable as the uppercase `K` used throughout — on the Spectrum these are the same variable, so this is not a bug. However, line 100 references `K$` before it has been assigned by the subroutine at line 160; this means the first column always prints the *previous* iteration’s formatted string rather than the freshly entered value. To print the entered value correctly in column 1, line 100 should call `GO SUB 160` before the `PRINT`, or lines should be reordered so the subroutine runs first. The keyword `LINE 60` in the `SAVE` command at line 210 causes the program to auto-run from line 60 when loaded. Several lines use conditional compilation-style comments (lines marked with embedded `REM` tokens in the middle of lines) to annotate optional sections, a creative if unconventional documentation approach in BASIC. ### Line Reference Table | Line(s) | Role | | --- | --- | | 10–50 | REM documentation blocks | | 60 | CLS and screen header | | 90 | INPUT prompt for number K | | 100 | Print column 1 (right-aligned at TAB 10) | | 110–120 | Derive K/3, format, print column 2 (optional) | | 130–140 | Derive ×2, format, print column 3 (optional) | | 150 | Loop back to INPUT | | 160 | Formatting subroutine entry/exit | | 170 | DEF FN K — two-decimal rounding | | 180 | DEF FN K$ — decimal string padding | | 190–200 | REM explanations of lines 170 and 180 | | 210 | SAVE with auto-run | ## Source Code ``` 10 REM \{16}\{2}THIS PROGRAM IS PRESENTED BY ALGIS E. GEDRIS\{16}\{0} 20 REM \{16}\{4}NUMBER PRINTOUT ON THE SCREEN IN COLUMNS\{16}\{0} 30 \{20}\{0}\{20}\{0}\{20}\{1} REM \{20}\{0}SETING UP FOR NUMBER PRINT-OUT IN DIFFERENT COLUMNS 40 \{20}\{1} REM \{20}\{0}\{20}\{1}\{20}\{0}LINES 110 THROUGH 140 CAN BE ELIMINATED FOR ONE COLUMN PRINTOUT 50 \{20}\{1} REM \{20}\{0} ALL \{20}\{1} REM \{20}\{0} STATEMENTS CAN BE ELIMINATED. 60 CLS :PRINT AT 3,0;"PRINT-OUT ANY DECIMALS NUMBERS IN COLUMNS" 90 INPUT "ENTER A NUMBER: ";k 100 PRINT TAB 10- LEN K$;K$; 110 \{20}\{1} LET K=K/3:GO SUB 160\{20}\{0} 120 \{20}\{1} PRINT TAB 20- LEN K$;K$;\{20}\{0} 130 \{20}\{1} LET K=K*2:GO SUB 160\{20}\{0} 140 \{20}\{1} PRINT TAB 30- LEN K$;K$;\{20}\{0} 150 GO TO 90 160 LET K= FN K(K):LET K$= FN K$(K, STR$ K):RETURN 170 DEF FN K(K)= INT (100*K+0.5)/100 180 DEF FN K$(K,K$)=K$+(".00" AND K= INT K)+("0" AND ("0"+K$)(LEN K$)=".") 190 \{20}\{1} REM \{20}\{0}IN LINE 170 THE NUMBER "100" DIFINES THAT ONLY TWO SIGNIFICANT NUMBERS WILL BE SHOWN.CHANGING 100 TO 1000 (TWO PLACES) WILL GIVE THREE SIGNIFICANT NUMBER PRINTOUT. 200 \{20}\{1} REM \{20}\{0}LINE 180 ADDS .00; (.5)0 AND "." TO THE NUMBER. 210 SAVE "DECIMALCOL" LINE 60 ```