0

Given the following code:

  IDENTIFICATION DIVISION.
  PROGRAM-ID. FABS.
  ENVIRONMENT DIVISION.
  DATA DIVISION.
  WORKING-STORAGE SECTION.

  01 NUM PIC 9 VALUE ZEROS.
  01 ABSVAL PIC 99 VALUE ZEROS.

  PROCEDURE DIVISION.
  PROGRAM-BEGIN.

  DISPLAY "This program returns the absolute value of a number.".
    DISPLAY SPACE.
  DISPLAY "Input value: " WITH NO ADVANCING.
  ACCEPT NUM.

  IF (NUM = -0) THEN
     COMPUTE ABSVAL = 0
  ELSE
        IF (NUM > 0) THEN
         COMPUTE ABSVAL = 0
        ELSE
           COMPUTE ABSVAL = ABSVAL * -1
        END-IF
  END-IF.

  DISPLAY "|", NUM "| = ", ABSVAL.
  PROGRAM-DONE.

  STOP RUN.

Why is the output zero? Is there something wrong? And how do you make a signed/negative input?

Bill Woodger
  • 12,968
  • 4
  • 38
  • 47
MCMLXXXIX
  • 23
  • 2
  • 6

2 Answers2

1

Thinking of your task, rather than why you get zero, it is easy.

Let's assume you get a signed value with your ACCEPT.

01  value-from-accept PIC S9.
01  absolute-value-for-output PIC 9.

MOVE value-from-accept TO absolute-value-for-output
DISPLAY 
        "|" 
        value-from-accept 
        "| = "
        absolute-value-for-output

You may think that something is wrong with the output from value-from-accept (depending on compiler) but you can always MOVE it to a numeric-edited field and DISPLAY that.


Tip: To reverse the sign of a signed field.

SUBTRACT field-to-reverse-sign 
                             FROM ZERO
  GIVING                     the-reversed-field

SUBTRACT is faster than MULTIPLY.


You have defined your field which is ACCEPTed as unsigned.

The first two "legs" of your nested-IF set ABSVAL to zero. The remaining leg takes the existing value of ABSVAL (from the VALUE ZEROS, so it is zero) and multiplies it by minus one. Getting -ve zero (possibly), but then storing it in an unsigned field. So ABSVAL will always be zero when you come to the DISPLAY.

You define a signed field by prefixing the PICture string with an S:

01  a-signed-field PIC S9(5).

Depending on your compiler, you can type a - when entering the data and it'll be held happily as a negative value in a signed field (which you have to define) or you have to code for it yourself.

Bill Woodger
  • 12,968
  • 4
  • 38
  • 47
  • I thought it will branch to the next one if the if-then statement is false? Why would the remaining leg take the existing value of ABSVAL then? – MCMLXXXIX Mar 25 '15 at 16:26
  • Because a COMPUTE is like an assignment statement. Let (the new value of) ABSVAL be equal to (the original value of) ABSVAL multiplied by minus one. – Bill Woodger Mar 25 '15 at 16:32
  • You don't want an absolute-value, do you? You want an absolute-value for a negative number, else zero? – Bill Woodger Mar 25 '15 at 16:33
  • Wait. I think there are errors in the code itself. Haha. I fixed it. It should be, COMPUTE ABSVAL = NUM, and COMPUTE ABSVAL = NUM * (-1). But COMPUTE ABSVAL = NUM * (-1) still don't work. – MCMLXXXIX Mar 25 '15 at 16:35
  • You would need to get the input of the data by ACCEPT working. Can't help on that, as I don't know which compiler you have, and ACCEPT can have many extensions per compiler. You can also look at my answer for how to do the absolute value... but yes, those new COMPUTEs should give the correct answer once you have signed values... – Bill Woodger Mar 25 '15 at 16:43
  • It worked. It just needed to be a constant like this 01 NUM-1 PIC S9 VALUE -1. Guess it really needed to be signed then. – MCMLXXXIX Mar 25 '15 at 17:36
  • It didn't *need* to have an initial value, but it you give it one and don't change it you'll certainly get the expected results. You should also try my other way to show yourself that working, and look at the tip. Be aware of how to use Accept for answers, but you can easily wait to see if something more useful comes in :-) – Bill Woodger Mar 25 '15 at 17:43
0

after your correction above

I am not sure how you are testing it but to just to ensure that the values are stored correct you may want to have both the fields signed i.e. pic S9 or pic S99. Its possible that without the preceding S (sign) the variables are not really storing the negative sign regardless of what the screen is showing.

pls observe what results you get then