Space Age in Cobol: Complete Solution & Deep Dive Guide
The Complete Guide to Algorithmic Thinking in Cobol: The Space Age Challenge
Calculating interplanetary age in Cobol requires a structured approach. It involves dividing the input seconds by the Earth-year constant (31,557,600) to get Earth years, then dividing that result by a specific planet's orbital period using Cobol's precise COMPUTE verb and meticulously defined PIC clauses for data storage.
You’ve heard the whispers, maybe even the jokes. Cobol: the ancient language of dinosaurs, the dusty relic powering behemoth mainframes in forgotten basements. Yet, this "dinosaur" processes over 3 trillion dollars in commerce every single day and powers 95% of all ATM swipes. The truth is, Cobol is not dead; it's a hidden giant, and understanding its logic is a superpower in the world of enterprise technology. But how do you even begin to tame such a beast? It feels rigid, verbose, and utterly alien compared to Python or JavaScript.
This is where the real journey begins. We're going to demystify Cobol by tackling a classic problem from the exclusive kodikra.com learning curriculum: calculating a person's age on different planets. This simple challenge is the perfect vehicle to learn Cobol's core principles: its rigid data structures, its powerful arithmetic precision, and its structured, readable procedural logic. By the end of this guide, you won't just have a working program; you'll have unlocked the fundamental mindset required to read, write, and maintain critical enterprise applications.
What Exactly is the Space Age Problem?
The premise is straightforward yet requires careful calculation. Given a person's age in seconds, our task is to write a program that can determine their equivalent age in years on Earth and various other planets in our solar system. The core of the problem lies in unit conversion, using a set of defined constants.
The foundational constant is the length of one Earth year in seconds:
- 1 Earth Year = 365.25 days
- 1 Earth Year = 31,557,600 seconds
To find the age on another planet, we first convert the input seconds to Earth years. Then, we use the target planet's orbital period (how long it takes to circle the sun relative to Earth) to find the final age. The orbital periods are provided as constants:
| Planet | Orbital Period (in Earth Years) |
|---|---|
| Mercury | 0.2408467 |
| Venus | 0.61519726 |
| Earth | 1.0 |
| Mars | 1.8808158 |
| Jupiter | 11.862615 |
| Saturn | 29.447498 |
| Uranus | 84.016846 |
| Neptune | 164.79132 |
For example, an age of 1,000,000,000 seconds is approximately 31.69 Earth years. On Mars, this would be 31.69 / 1.8808158, which equals roughly 16.85 Martian years.
Why Solve This in Cobol? The Power of Precision
You might ask, "Why not just use Python and a few lines of code?" It's a valid question. However, using Cobol for this problem teaches us something profoundly important about software engineering, especially in finance, insurance, and government sectors: the absolute necessity of precision and structured data.
Cobol forces you to think about your data before you write a single line of logic. You must declare every variable, its type, and its exact size using the PICTURE (PIC) clause. This isn't a limitation; it's a feature. It prevents the subtle floating-point errors that can plague other languages and lead to catastrophic financial miscalculations. This exercise is less about space and more about mastering the fixed-point arithmetic and data definition that makes Cobol uniquely reliable for mission-critical systems.
By solving this, you will gain hands-on experience with:
- Data Division Mastery: Defining constants and variables with exact precision.
- Procedural Logic: Structuring code in readable paragraphs and sections.
- Arithmetic Verbs: Using
COMPUTEfor complex, readable calculations. - Control Flow: Implementing multi-case logic with the powerful
EVALUATEstatement.
How to Build the Cobol Solution: A Deep Dive
A Cobol program is like a well-organized book, divided into distinct sections called DIVISIONs. For our Space Age calculator, we will primarily use the IDENTIFICATION, DATA, and PROCEDURE divisions.
The Overall Logic Flow
Before we write code, let's visualize the program's journey from input to output. The logic is a clear, sequential process perfect for Cobol's procedural nature.
● Start Program
│
▼
┌───────────────────────────┐
│ Define Constants & Vars │
│ (In DATA DIVISION) │
└────────────┬──────────────┘
│
▼
┌───────────────────────────┐
│ Accept Input (Seconds) │
└────────────┬──────────────┘
│
▼
┌───────────────────────────┐
│ COMPUTE Earth Years │
│ (Seconds / Earth-Sec-Yr) │
└────────────┬──────────────┘
│
▼
◆ Evaluate Target Planet
├───────────────────────────┐
│ WHEN 'MERCURY' │
│ Compute Mercury Age │
├───────────────────────────┤
│ WHEN 'VENUS' │
│ Compute Venus Age │
├───────────────────────────┤
│ ... (and so on) │
└────────────┬──────────────┘
│
▼
┌───────────────────────────┐
│ Display Result │
└────────────┬──────────────┘
│
▼
● End Program
The Complete Cobol Source Code
Here is the full, commented source code for the Space Age calculator. This program is designed for clarity and follows modern Cobol best practices.
IDENTIFICATION DIVISION.
PROGRAM-ID. SpaceAgeCalculator.
AUTHOR. Kodikra.
DATE-WRITTEN. 2024-05-21.
*>****************************************************************
*> This program calculates age on different planets given an
*> age in seconds. It is a module from the kodikra.com
*> exclusive Cobol learning path.
*>****************************************************************
DATA DIVISION.
WORKING-STORAGE SECTION.
*> --- Constants for Calculations ---
01 C-EARTH-SECONDS-PER-YEAR PIC 9(8)V99 VALUE 31557600.00.
01 C-ORBITAL-PERIODS.
05 C-MERCURY PIC 9V9999999 VALUE 0.2408467.
05 C-VENUS PIC 9V9999999 VALUE 0.61519726.
05 C-EARTH PIC 9V9 VALUE 1.0.
05 C-MARS PIC 9V9999999 VALUE 1.8808158.
05 C-JUPITER PIC 99V999999 VALUE 11.862615.
05 C-SATURN PIC 99V999999 VALUE 29.447498.
05 C-URANUS PIC 99V999999 VALUE 84.016846.
05 C-NEPTUNE PIC 999V99999 VALUE 164.79132.
*> --- Input and Output Variables ---
01 WS-INPUT-SECONDS PIC 9(10).
01 WS-TARGET-PLANET PIC X(10).
01 WS-CALCULATIONS.
05 WS-EARTH-YEARS PIC 9(4)V9999999.
05 WS-PLANET-AGE PIC 9(4)V99.
01 WS-DISPLAY-AGE PIC ZZZ9.99.
PROCEDURE DIVISION.
1000-MAIN-LOGIC.
PERFORM 2000-GET-INPUT
PERFORM 3000-CALCULATE-AGE
PERFORM 4000-DISPLAY-RESULT
STOP RUN.
2000-GET-INPUT.
*> For this example, we hardcode the values.
*> In a real application, you might use ACCEPT.
MOVE 1000000000 TO WS-INPUT-SECONDS.
MOVE "MARS" TO WS-TARGET-PLANET.
DISPLAY "Calculating age for " WS-INPUT-SECONDS " seconds on "
WS-TARGET-PLANET.
3000-CALCULATE-AGE.
*> Step 1: Convert input seconds to Earth years for a baseline.
COMPUTE WS-EARTH-YEARS ROUNDED =
WS-INPUT-SECONDS / C-EARTH-SECONDS-PER-YEAR.
*> Step 2: Use EVALUATE to find the age on the target planet.
EVALUATE FUNCTION UPPER-CASE(WS-TARGET-PLANET)
WHEN "MERCURY"
COMPUTE WS-PLANET-AGE ROUNDED =
WS-EARTH-YEARS / C-MERCURY
WHEN "VENUS"
COMPUTE WS-PLANET-AGE ROUNDED =
WS-EARTH-YEARS / C-VENUS
WHEN "EARTH"
COMPUTE WS-PLANET-AGE ROUNDED =
WS-EARTH-YEARS / C-EARTH
WHEN "MARS"
COMPUTE WS-PLANET-AGE ROUNDED =
WS-EARTH-YEARS / C-MARS
WHEN "JUPITER"
COMPUTE WS-PLANET-AGE ROUNDED =
WS-EARTH-YEARS / C-JUPITER
WHEN "SATURN"
COMPUTE WS-PLANET-AGE ROUNDED =
WS-EARTH-YEARS / C-SATURN
WHEN "URANUS"
COMPUTE WS-PLANET-AGE ROUNDED =
WS-EARTH-YEARS / C-URANUS
WHEN "NEPTUNE"
COMPUTE WS-PLANET-AGE ROUNDED =
WS-EARTH-YEARS / C-NEPTUNE
WHEN OTHER
DISPLAY "ERROR: Invalid planet name provided."
MOVE 0 TO WS-PLANET-AGE
END-EVALUATE.
4000-DISPLAY-RESULT.
MOVE WS-PLANET-AGE TO WS-DISPLAY-AGE.
DISPLAY "Calculated Age: " FUNCTION TRIM(WS-DISPLAY-AGE)
" years.".
END PROGRAM SpaceAgeCalculator.
Where the Magic Happens: A Detailed Code Walkthrough
Let's dissect the program section by section to understand the "Cobol way" of thinking.
1. IDENTIFICATION DIVISION
This is the simplest part. It's metadata for your program. The PROGRAM-ID is mandatory and gives your program a name. Other entries like AUTHOR are good practice for documentation.
2. DATA DIVISION and WORKING-STORAGE SECTION
This is the heart of a Cobol program's structure. Here, we pre-define every single piece of memory our program will use. There are no dynamic variables created on the fly.
Constants (C- prefix):
01 C-EARTH-SECONDS-PER-YEAR PIC 9(8)V99 VALUE 31557600.00.
01 C-ORBITAL-PERIODS.
05 C-MERCURY PIC 9V9999999 VALUE 0.2408467.
...
01and05are level numbers, creating a hierarchical data structure.C-ORBITAL-PERIODSis a group item containing several elementary items.PICstands for Picture Clause. It defines the variable's type and size.9represents a numeric digit.PIC 9(8)means eight digits.Vrepresents an implied decimal point. It does not occupy storage but tells the Cobol compiler where the decimal point is for arithmetic operations. This is the key to Cobol's fixed-point precision.PIC 9V9999999stores a number like0.2408467as the integer2408467internally, but the compiler knows it has 7 decimal places.
Variables (WS- prefix):
01 WS-INPUT-SECONDS PIC 9(10).
01 WS-TARGET-PLANET PIC X(10).
01 WS-DISPLAY-AGE PIC ZZZ9.99.
PIC 9(10)defines a 10-digit integer.PIC X(10)defines an alphanumeric string of 10 characters.PIC ZZZ9.99is an "edited" numeric field for display. TheZs suppress leading zeros, and the.is a real decimal point inserted for readability when the value is displayed.
3. PROCEDURE DIVISION
This division contains the executable logic, organized into paragraphs (like functions or methods). Our program's entry point is the first paragraph, 1000-MAIN-LOGIC.
The Main Controller: 1000-MAIN-LOGIC
1000-MAIN-LOGIC.
PERFORM 2000-GET-INPUT
PERFORM 3000-CALCULATE-AGE
PERFORM 4000-DISPLAY-RESULT
STOP RUN.
This paragraph acts as a high-level controller. The PERFORM verb calls other paragraphs in sequence, making the code extremely readable and similar to a table of contents. After the sequence is complete, STOP RUN terminates the program.
The Calculation Core: 3000-CALCULATE-AGE
This is where the main business logic resides. Let's visualize the arithmetic flow in more detail.
┌───────────────────────────┐
│ WS-INPUT-SECONDS │
│ (e.g., 1,000,000,000) │
└────────────┬──────────────┘
│
▼ (DIVIDE BY C-EARTH-SECONDS-PER-YEAR)
│
┌───────────────────────────┐
│ WS-EARTH-YEARS │
│ (Result: 31.6880876) │
└────────────┬──────────────┘
│
▼ (EVALUATE WS-TARGET-PLANET)
│
┌───────────────────────────┐
│ Case: "MARS" │
│ (DIVIDE BY C-MARS) │
└────────────┬──────────────┘
│
▼
┌───────────────────────────┐
│ WS-PLANET-AGE │
│ (Result: 16.85) │
└───────────────────────────┘
The code implements this with two key statements:
COMPUTE: This verb is the modern, flexible way to perform arithmetic in Cobol. It allows for complex formulas in a single statement, much like other languages. TheROUNDEDclause instructs the compiler to perform standard rounding if the result has more decimal places than the receiving variable can hold.COMPUTE WS-EARTH-YEARS ROUNDED = WS-INPUT-SECONDS / C-EARTH-SECONDS-PER-YEAR.EVALUATE: This is Cobol's equivalent of aswitchorcasestatement. It is far more readable and efficient than a long chain of nestedIF...ELSE IF...statements. We useFUNCTION UPPER-CASEto make the comparison case-insensitive, which is a robust programming practice.EVALUATE FUNCTION UPPER-CASE(WS-TARGET-PLANET) WHEN "MERCURY" COMPUTE WS-PLANET-AGE ROUNDED = WS-EARTH-YEARS / C-MERCURY WHEN "VENUS" ... WHEN OTHER DISPLAY "ERROR: Invalid planet name provided." END-EVALUATE.
Alternative Approaches and Considerations
While our solution is robust, there are other ways to structure the logic in Cobol, each with its own trade-offs.
Alternative 1: Using an Array (Table) and a Loop
For a more scalable solution, you could define the planet names and their orbital periods in a table (Cobol's term for an array). You could then use a PERFORM VARYING loop to search for the target planet and retrieve its orbital period.
Pros:
- More Scalable: Adding a new planet only requires adding an entry to the table, not a new
WHENclause. - Reduces Code Duplication: The calculation logic is written only once inside the loop.
Cons:
- More Complex: Requires understanding of table definition (
OCCURSclause) and subscripting (indexing). - Slightly Slower: A linear search through a table can be less performant than a direct jump from an
EVALUATEstatement, though the difference is negligible for this small dataset.
Alternative 2: Using Classic IF/ELSE IF Statements
Before the EVALUATE statement was introduced in the Cobol-85 standard, developers relied on nested IF statements.
IF WS-TARGET-PLANET = "MERCURY"
COMPUTE WS-PLANET-AGE = WS-EARTH-YEARS / C-MERCURY
ELSE
IF WS-TARGET-PLANET = "VENUS"
COMPUTE WS-PLANET-AGE = WS-EARTH-YEARS / C-VENUS
ELSE
...
END-IF
END-IF.
Pros:
- Backwards Compatible: Works on very old Cobol compilers.
Cons:
- Poor Readability: This structure quickly becomes a "staircase" of code that is difficult to read and maintain.
- Error-Prone: It's easy to make a mistake with the nesting and
END-IFscopes. Modern best practice strongly favorsEVALUATEfor multi-case selection.
Frequently Asked Questions (FAQ)
Is Cobol still relevant today?
Absolutely. While it's not used for new web or mobile apps, Cobol is the backbone of the global financial system. Mainframes at major banks, insurance companies, and government agencies run billions of lines of Cobol code. There is a high demand and low supply of skilled Cobol programmers to maintain and modernize these critical systems, making it a valuable and stable career path.
What does PIC 9(4)V99 mean in Cobol?
This is a PICTURE clause defining a numeric variable. 9(4) means it can hold 4 digits to the left of the decimal. V is the implied decimal point (it is not stored as a character). 99 means it holds 2 digits to the right of the decimal. The total storage is for 6 digits (e.g., 1234.56 would be stored as the number 123456), but the compiler treats it as a number with two decimal places during calculations.
Why is COMPUTE often preferred over verbs like ADD or DIVIDE?
Older Cobol code used verbose statements like DIVIDE A BY B GIVING C. The COMPUTE verb, introduced in later standards, allows for algebraic expressions (e.g., COMPUTE C = (A + B) / D). It is more concise, readable for complex formulas, and aligns better with how arithmetic is written in modern languages. It is generally considered best practice for all but the simplest calculations.
What is the difference between WORKING-STORAGE SECTION and FILE SECTION?
Both are in the DATA DIVISION. The WORKING-STORAGE SECTION is used to define variables, constants, and data structures that exist only in the program's memory. The FILE SECTION is used to define the record layout of external files that the program will read from or write to, linking program variables to disk storage.
How do I compile and run a Cobol program?
You need a Cobol compiler. A popular open-source option is GnuCOBOL (formerly OpenCOBOL). The compilation process is typically a two-step command in a terminal:
# Compile the source code into a native module
cobc -x -free your-program-name.cbl
# Run the compiled executable
./your-program-name
The -x flag creates an executable, and -free allows for more flexible source code formatting.
Can Cobol handle floating-point numbers?
Yes, but its strength lies in fixed-point decimal arithmetic. Native Cobol uses PIC clauses with an implied decimal (V) for precise financial math. Modern Cobol compilers also support binary floating-point types (COMP-1, COMP-2) for scientific calculations, but fixed-point is preferred for business logic to avoid the rounding errors inherent in floating-point representations.
Why is the IDENTIFICATION DIVISION mandatory?
It is a fundamental part of the Cobol language specification. At a minimum, it must contain the PROGRAM-ID, which assigns a name to the program module. This name is used by the operating system and other programs to call it. It establishes the program as a distinct, identifiable unit of code.
Conclusion: From Space Age to Enterprise Ready
We've journeyed from a simple question about planetary ages to a deep understanding of Cobol's core philosophy. The Space Age problem, when viewed through the Cobol lens, ceases to be a simple math puzzle. It becomes a lesson in structure, precision, and deliberate design. You've learned how to define data with unwavering accuracy using PIC clauses, how to orchestrate logic with PERFORM and paragraphs, and how to make clean decisions with the EVALUATE statement.
These are not just esoteric skills for a legacy language. They are the building blocks of the robust, reliable systems that power our world's economy. By mastering these concepts, you are well on your way to understanding the mindset required to work with enterprise-level code. Your journey doesn't end here; this is just one module in a much larger world.
To continue building your skills, explore our complete Cobol 1 learning path, which is packed with more challenges to solidify your knowledge. And for a broader understanding of the language itself, be sure to master the fundamentals of Cobol with our detailed guide.
Disclaimer: All code in this article was developed and tested using GnuCOBOL 3.1.2. Syntax and features may vary slightly with other compilers like those from IBM or Micro Focus.
Published by Kodikra — Your trusted Cobol learning resource.
Post a Comment