IDENTIFICATION DIVISION.
PROGRAM-ID. MP2.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 AMOUNT PIC 9(4)V9(4).
01 AMTDIV PIC 99V9(4).
01 CURR PIC X(3).
88 PHP VALUE "PHP" "php".
88 USA VALUE "USD" "usd".
88 CND VALUE "CAD" "cad".
88 AUS VALUE "AUD" "aud".
01 RECURR PIC X(3).
88 PHPK VALUE "PHP" "php".
88 USAK VALUE "USD" "usd".
88 CNDK VALUE "CAD" "cad".
88 AUSK VALUE "AUD" "aud".
01 CONFIRM PIC X.
88 AGREE VALUE "Y" "y".
88 DISAGREE VALUE "N" "n".
PROCEDURE DIVISION.
START-UP.
DISPLAY "CURRENCY LIST".
DISPLAY "USD (US DOLLARS), CAD (CANADIAN DOLLAR)".
DISPLAY "PHP (PHILIPPINE PESO), AUD (AUSTRALIAN DOLLAR)".
DISPLAY " ".
MAIN-ROUTINE.
DISPLAY "ENTER AMOUNT: ".
ACCEPT AMOUNT.
DISPLAY "ENTER SOURCE CURRENCY: "
ACCEPT CURR.
IF PHP
DISPLAY "PHILLIPINE PESO"
DISPLAY "ENTER TARGET CURRENCY: "
ACCEPT RECURR
IF USAK
DISPLAY "AMERICAN DOLLAR"
MOVE 435450 TO AMTDIV
ELSE IF CNDK
DISPLAY "CANADIAN DOLLAR"
MOVE 416707 TO AMTDIV
ELSE IF AUSK
DISPLAY "AUSTRALIAN DOLLAR"
MOVE 410325 TO AMTDIV
ELSE
DISPLAY "INVALID OPTION"
ELSE IF USA
DISPLAY "AMERICAN DOLLAR"
DISPLAY "ENTER TARGET CURRENCY: "
ACCEPT RECURR
IF PHPK
DISPLAY "PHILIPPINE PESO"
MOVE 000230 TO AMTDIV
ELSE IF CNDK
DISPLAY "CANADIAN DOLLAR"
MOVE 009574 TO AMTDIV
ELSE IF AUSK
DISPLAY "AUSTRALIAN DOLLAR"
MOVE 009423 TO AMTDIV
ELSE
DISPLAY "INVALID OPTION"
ELSE IF CND
DISPLAY "CANADIAN DOLLAR"
DISPLAY "ENTER TARGET CURRENCY: "
ACCEPT RECURR
IF PHPK
DISPLAY "PHILIPPINE PESO"
MOVE 000240 TO AMTDIV
ELSE IF USAK
DISPLAY "AMERICAN DOLLAR"
MOVE 010442 TO AMTDIV
ELSE IF AUSK
DISPLAY "AUSTRALIAN DOLLAR"
MOVE 009837 TO AMTDIV
ELSE
DISPLAY "INVALID OPTION"
ELSE IF AUS
DISPLAY "AUSTRALIAN DOLLAR"
DISPLAY "ENTER TARGET CURRENCY: "
ACCEPT RECURR
IF PHPK
DISPLAY "PHILIPPINE PESO"
MOVE 000244 TO AMTDIV
ELSE IF CNDK
DISPLAY "CANADIAN DOLLAR"
MOVE 010166 TO AMTDIV
ELSE IF USAK
DISPLAY "AMERICAN DOLLAR"
MOVE 010612 TO AMTDIV
ELSE
DISPLAY "INVALID OPTION"
ELSE
DISPLAY "INVALID OPTION".
DIVIDE AMOUNT BY AMTDIV GIVING AMOUNT.
DISPLAY "CONVERTED AMOUNT: "AMOUNT.
ONE-MORE-TRY.
DISPLAY "WOULD YOU LIKE TO CONVERT ANOTHER CURRENCY? [Y/N]?".
ACCEPT CONFIRM.
IF AGREE
PERFORM MAIN-ROUTINE THRU ONE-MORE-TRY
ELSE IF DISAGREE
PERFORM END-PGM
ELSE
DISPLAY "INVALID OPTION"
PERFORM ONE-MORE-TRY.
END-PGM.
STOP RUN.

- 77,302
- 8
- 62
- 84

- 39
- 1
- 4
-
Would suggest using Evaluate true (see http://www.fluffycat.com/COBOL/Evaluate/) instead of else if structure – Bruce Martin Nov 26 '13 at 00:45
2 Answers
You have two problems in getting your DIVIDE to work.
In order of occurrence:
You ACCEPT your AMOUNT. Your AMOUNT has an implied decimal place (the V in the PICture string), yet ACCEPT is going to, for your purpose, ignore this implied decimal. There will be no alignment with what the user types at the screen. There is more than one way to deal with this, perhaps the simplest for your purpose it to look at the Intrinsic FUNCTION NUMVAL.
You, as @Magoo indicated, do not use decimal points in your literals, so they are treated as whole numbers, so effectively the figures you expect to be used for the currency conversion are multiplied by 10,000 and left-truncated.
When reporting a problem it is a good idea to show the input data which gave you the problem, the result you actually achieved, and the expected result. If you can work out what is happening but are unsure how to correct it, that is a bonus.
You have tagged Coding-Style. I think you might want to remove that by editing your question. The people interested in the Coding-Style tag are probably not too aware of COBOL. If you have a future Career as a COBOL programmer, your style is going to be more or less dictated by the site standards of where you work, and will change from site to site. You can, of course, develop your own style, but it develops, it isn't just given to you. Knowing the messes you can get into helps you develop style (technique) in avoiding getting there. You'll still need to know how things happen, because not all programmers take the time to develop anything in the way of style.
Read through some of the questions here, and see if you get some ideas about common problems.

- 12,968
- 4
- 38
- 47
Try putting the decimal point into your constants. COBOL is smart enough to align the decimal with the V
(virtual decimal point) and maps the storage method provided by the PIC
TURE so that relatively-efficient sdata storage can be translated back-and-forth to human-readable form.
Never use PERFORM THROUGH
- it produces layout-dependent code.
Your PERFORM MAIN-ROUTINE THRU ONE-MORE-TRY
should be GO TO PERFORM MAIN-ROUTINE
PERFORM END-PGM
should be GO TO END-PGM
and PERFORM ONE-MORE-TRY.
should be GO TO ONE-MORE-TRY.
A PERFORM
executes the code starting at the target label as a subroutine, so your current structure is endlessly building a return-address stack until you bail out via the STOP RUN.

- 77,302
- 8
- 62
- 84
-
In COBOL, PERFORMing a section or paragraph does not build a return address stack as you might be familiar with from call/return semantics implemented in most other programming languages. This essay on [COBOL Transfer of Control](http://www3.sympatico.ca/bredam/TransferControl.html) explains how the PERFORM verb in COBOL really works. It is a bit of a tough read but worth the "investment" if you really want to understand the COBOL language. – NealB Nov 25 '13 at 14:18
-
Fair 'nuff, @NealB - The precise mechanism is a matter for the cognescenti. Traditionally, the hardware doesn't support a stack. The principle is better understood in terms of a stack in my view, and it's better not to distract beginners with the minutae. – Magoo Nov 25 '13 at 16:11