COBOL UNSTRING negative numeric string

Post Reply

Topic author
meyer_d
Contributor
Posts: 13
Joined: Tue Oct 31, 2023 10:18 pm
Reputation: 0
Status: Offline

COBOL UNSTRING negative numeric string

Post by meyer_d » Tue May 14, 2024 10:41 pm

I'm using the VAX COBOL compiler.

The UNSTRING statement can parse a string of numeric characters into a display numeric item (PIC 9(n)), but terminates with the error '%COB-F-INVDECDIG, invalid decimal digit: "-"' if the numeric string has a leading or trailing negative sign, even if the receiving item is declared PIC S9(n). Is there any way to get UNSTRING (or another statement) to parse an input negative number?


hein
Valued Contributor
Posts: 51
Joined: Fri Dec 25, 2020 5:20 pm
Reputation: 0
Status: Offline

Re: COBOL UNSTRING negative numeric string

Post by hein » Wed May 15, 2024 12:30 pm

VAX ? Really? Compiler/rtl/vms version?

Did the behavior change or is this a first try?

Can you perhaps post a small working (well, failing) example to make it easier for us to try on Alpha or Itanium... or X86?
If this is a bug it may well have been fixed.

Hein.

User avatar

arne_v
Master
Posts: 412
Joined: Fri Apr 17, 2020 7:31 pm
Reputation: 0
Location: Rhode Island, USA
Status: Offline
Contact:

Re: COBOL UNSTRING negative numeric string

Post by arne_v » Wed May 15, 2024 7:50 pm

I don't do COBOL and this is on VMS x86-64 not VAX, but:

Code: Select all

$ type usdemo.cob
identification division.
program-id.usdemo.
*
data division.
working-storage section.
01 ui pic 9(8) display.
01 si pic s9(8) display.
01 t  pic x(10).
*
procedure division.
main-paragraph.
    move 10 to ui
    display "unsigned 10 = " ui
    move 10 to si
    display "signed 10   = " si
    move -10 to si
    display "signed -10  = " si
    move "10" to t
    unstring t into ui
    display t " -> " ui
    move "10" to t
    unstring t into si
    display t " -> " si
    move "-10" to t
    unstring t into si
    display t " -> " si " (WRONG)"
    move "1}" to t
    unstring t into si
    display t " -> " si " (WRONG)"
    move "-10" to t
    compute si = function numval(t)
    display "numval(" t ") = " si
    stop run.
$ cob usdemo
$ lin usdemo
$ run usdemo
unsigned 10 = 00000010
signed 10   = 0000001{
signed -10  = 0000001}
10         -> 00000010
10         -> 0000001{
-10        -> 0000001{ (WRONG)
1}         -> 0000000A (WRONG)
numval(-10       ) = 0000001}
You could try if the NUMVAL function works on VAX.
Arne
arne@vajhoej.dk
VMS user since 1986


Topic author
meyer_d
Contributor
Posts: 13
Joined: Tue Oct 31, 2023 10:18 pm
Reputation: 0
Status: Offline

Re: COBOL UNSTRING negative numeric string

Post by meyer_d » Wed May 15, 2024 8:44 pm

hein wrote:
Wed May 15, 2024 12:30 pm
VAX ? Really? Compiler/rtl/vms version?
Yes, really. I'm using a VAX 7000/640 (Living Computer's ROSENCRANTZ host; I think it's running on real hardware) running OpenVMS V7.3. The compiler is Digital VAX COBOL V5.5-56. I don't know where to look-up the RTL version.
Did the behavior change or is this a first try?
First try. I'm re-learning COBOL by working through programming problems on CodeAbbey.com, many of which assume that you can feed numeric test data to the program from the user's terminal. I realize that this kind of interaction is not really COBOL's design target, and that it would not be to hard to write my own string-to-numeric parser, but I'd like to see how much I can accomplish with facilities that are build-in to COBOL-85.
Can you perhaps post a small working (well, failing) example to make it easier for us to try on Alpha or Itanium... or X86?

Code: Select all

       IDENTIFICATION DIVISION.
       PROGRAM-ID. TUNST.
      * TUNST - TEST UNSTRING COMMAND

       DATA DIVISION.
       WORKING-STORAGE SECTION.

       01  SOURCE-STR  PIC X(80)  VALUE '-8'.
       01  N  PIC S9(6).

       PROCEDURE DIVISION.

       MAIN.
           DISPLAY 'PROGRAM TUNST'.
           UNSTRING SOURCE-STR DELIMITED BY SPACE INTO N.
           DISPLAY 'N: /', N, '/'.
           STOP RUN.

Here's how it fails:

Code: Select all

 $ run tunst
PROGRAM TUNST
%COB-F-INVDECDIG, invalid decimal digit: "-"
%TRACE-F-TRACEBACK, symbolic stack dump follows
module name     routine name                     line       rel PC    abs PC

                                                           00079145  00079145
Added in 12 minutes 20 seconds:
arne_v wrote:
Wed May 15, 2024 7:50 pm
You could try if the NUMVAL function works on VAX.
It looks like VAX COBOL has NUMVAL, and it might do the trick for me.

Code: Select all

       IDENTIFICATION DIVISION.
       PROGRAM-ID. TNUMVAL.

       DATA DIVISION.
       WORKING-STORAGE SECTION.

       01  SOURCE-STR  PIC X(80)  VALUE '-8'.
       01  N  PIC S9(6).

       PROCEDURE DIVISION.

       MAIN.
           DISPLAY 'PROGRAM TNUMVAL'.
           COMPUTE N = FUNCTION NUMVAL(SOURCE-STR).
           DISPLAY 'N: /', N, '/'.
           STOP RUN.

Code: Select all

 $ RUN TNUMVAL
PROGRAM TNUMVAL
N: /00000Q/
Which is how you say '-8' in COBOL.

... Though it would still be neater if there were a way to get UNSTRING to parse negative numbers since it can do the trick for positives.
Last edited by meyer_d on Wed May 15, 2024 9:09 pm, edited 3 times in total.


hein
Valued Contributor
Posts: 51
Joined: Fri Dec 25, 2020 5:20 pm
Reputation: 0
Status: Offline

Re: COBOL UNSTRING negative numeric string

Post by hein » Fri May 17, 2024 10:07 am

I tried a few things, but no joy with UNSTRING. It does not interpret the data. Per doc:
"dest-string - is the identifier of an alphanumeric, alphabetic, or numeric DISPLAY data item. It is the receiving field for the data from src-string"

The backend move from the unstringed element into the dest-string, seems check better on the VAX, but neither 'properly' interpret the string. In Integrity you for example can get: N: /0000-8/ - no error, but no good either. It's better to have the error.

To use UNSTRING for free format number parsing you'd have to do something like UNSTRING ...
DELIMITED BY "-" OR ALL " " DELIMITER IN delim-dest. Yuck.


>>> N: /00000Q/ .... Which is how you say '-8' in COBOL.

YES , for straight S9(x) becoming a trailing overpunch.

To 'see' the sign you would need 01 N PIC S9(6) SIGN LEADING|TRAIING SEPARATE.

So indeed best go NUMVAL COBOL intrinsic, or one of the LIB$ VMS routines.
Hein.

Code: Select all

Table 5–11 Positive and Negative Signs for All Numeric Digits
Digit Values Positive Sign Negative Sign
0 {, [, ?, or 0 }, ], :, or !
1 A or 1 J
2 B or 2 K
3 C or 3 L
4 D or 4 M
5 E or 5 N
6 F or 6 O
7 G or 7 P
8 H or 8 Q
9 I or 9 R

User avatar

arne_v
Master
Posts: 412
Joined: Fri Apr 17, 2020 7:31 pm
Reputation: 0
Location: Rhode Island, USA
Status: Offline
Contact:

Re: COBOL UNSTRING negative numeric string

Post by arne_v » Fri May 17, 2024 2:18 pm

I still think it is something that should be fixed.

It does work in GNUCobol:

Code: Select all

C:\Work\Cobol>type usdemo.cob
identification division.
program-id.usdemo.

data division.
working-storage section.
01 ui pic 9(8) display.
01 si pic s9(8) display.
01 t  pic x(10).

procedure division.
main-paragraph.
    move 10 to ui
    display "unsigned 10 = " ui
    move 10 to si
    display "signed 10   = " si
    move -10 to si
    display "signed -10  = " si
    move "10" to t
    unstring t into ui
    display t " -> " ui
    move "10" to t
    unstring t into si
    display t " -> " si
    move "-10" to t
    unstring t into si
    display t " -> " si " (CORRECT)"
    move "1}" to t
    unstring t into si
    display t " -> " si " (WRONG)"
    move "-10" to t
    compute si = function numval(t)
    display "numval(" t ") = " si
    stop run.

C:\Work\Cobol>runcob usdemo

C:\Work\Cobol>call "C:\Native\32bit\GC32-BDB\set_env.cmd"

Information: batch was called alread from "C:\Native\32bit\GC32-BDB\"
             skipping environment setting...

cobc (GnuCOBOL) 3.2.0
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Keisuke Nishida, Roger While, Ron Norman, Simon Sobisch, Edward Hart
Built     Jul 28 2023 19:10:09
Packaged  Jul 28 2023 17:02:56 UTC
C version (MinGW) "9.2.0"

GnuCOBOL 3.2.0 (Jul 28 2023 19:08:58), (MinGW) "9.2.0"
GMP 6.2.1, cJSON 1.7.14, PDCursesMod 4.3.7, BDB 18.1.40

C:\Work\Cobol>cobc -Wall -O3 -free -x usdemo.cob

C:\Work\Cobol>usdemo
unsigned 10 = 00000010
signed 10   = +00000010
signed -10  = -00000010
10         -> 00000010
10         -> +00000010
-10        -> -00000010 (CORRECT)
1}         -> +00000001 (WRONG)
numval(-10       ) = -00000010
Added in 14 minutes 37 seconds:
To be more specific:
- the VAX behavior of giving an error is OK (but does not matter much as there will be no fixes for VAX anyway)
- the newer behavior of giving wrong result is not OK and should be fixed
Arne
arne@vajhoej.dk
VMS user since 1986

Post Reply