Search This Blog

Friday, October 30, 2009

Understanding COBOL for .Net Data Types


How many feel like maybe you must of drank those 99 bottles of beer?  Head spinning like a top?

COBOL?  That can't be COBOL code Alex posted.  Or is it?

My favorite email on Alex's post had a comment which I'm sure applies to many

"...if that is COBOL, I'm in deep !#$!"

Well, I have good news and bad news.  Good news is that it is COBOL. 

Or was that the bad news? *grin*

Never fear.  You too can read and write latin errr COBOL for .Net.  How you ask?

Well, let's start at what I consider the basics (some may argue), data types.

All of us are familiar with the syntax of defining COBOL variables using things like PIC X(11) and PIC S9(04) COMP, etc. For instance, defining a COBOL variable containing a string of text is as simple as:

01  WS-VAR1              PIC X(11) VALUE "HELLO WORLD".

More good news...  In the COBOL of today, this still works just fine.  However, to facilitate working in the .Net world, a few new data types have been added to the language.  I've listed them out below, along with their corresponding COBOL equivelant.

  • binary-char  --->  PIC S9(2) COMP-5
  • binary-char unsigned ---> PIC 9(2) COMP-5
  • binary-short ---> PIC S9(4) COMP-5
  • binary-short unsigned ---> PIC 9(4) COMP-5
  • binary-long ---> PIC S9(9) COMP-5
  • binary-long unsigned ---> PIC 9(9) COMP-5
  • binary-double ---> PIC S9(18) COMP-5
  • binary-double unsigned ---> PIC 9(18) COMP-5
  • float-short ---> USAGE COMP-1
  • float-long ---> USAGE COMP-2
  • object ---> USAGE OBJECT REFERENCE  
So, when you see a line of code in a COBOL for .Net program which looks like this:

01  WS-VAR1 BINARY-SHORT.

You can translate it to what you are familiar with:

01  WS-VAR1  PIC S9(4) COMP-5.

Simple enough huh?  *smile*
 
I believe these new data types were created to help you and I make sure we move the data into the right field with the proper sizing already figured out.  I can recall quite a few times where I was trying to mix languages such as C and COBOL and having to manually write what I called a bridge routine to convert a C data type to fit into the appropriately defined COBOL variable.  With these new data types, the guesswork is taken out of it.  Working with a C# binary long field and need to call a COBOL program?  Not a problem.  Just use a COBOL variable defined like so:

01  WS-VAR1 BINARY-LONG.

and then call your COBOL program passing it the data from the C# routine to the COBOL program appropriately (Rick covers the how on some of his postings).

Ok, now for the twist...  There have also been a handful of new data types added which just didn't exist in the COBOL of yesteryear.  I've listed them below and their equivelent C# data type.
 
  • character ---> char
  • condition-value ---> bool
  • decimal ---> decimal
  • string ---> string

These "new" data types have some pretty interesting features which you will want to look at.  And believe it or not, I think you might find them handy.  First we will take a look at the COBOL data type of "character".  Character is for defining and storing a single character of data.  That's it.  Nothing more to it. 

But what if you need to define a string of characters?  Traditional COBOL would maybe have you put something like Character(11) or some such together.  That would require you to know how many characters you wished to store in the field.  So, toss that out.

In the COBOL for .Net world, you would use the data type "string" for storing text, that is, a number of characters. Just like in C#, a COBOL string is immutable (say that fast 5 times), which means that a string is never changed after it has been created. When using routines which change a string, the actual string is not changed - a new string is returned instead.

01  WS-VAR1  STRING

Several of you are probably thinking "But what about an internal table" and how does it work.  That is straight forward as well, probably even better than you would expect.  Take a look:

01 WS-ARRAY-OF-LONGS     BINARY-LONG OCCURS ANY.

This statement declares a table or array (a better description) of Binary-Longs, but notice the word ANY appearing at the end.  This allows the length/size of the array to be decided at runtime.


01 WS-ARRAY-OF-STRINGS   STRING OCCURS ANY.

Same thing with the statement above.  Cool stuff huh?

Next up, an item I think long over due,  the boolean variable type "condition-value".

01  WS-TRUE-FALSE-FLAG                 PIC X(01).
      88  WS-TRUE                                    VALUE "T".
      88  WS-FALSE                                  VALUE "F".

With the "condition-value" this same statement could be done a bit differently.

01  WS-TRUE-FALSE-FLAG   CONDITION-VALUE.

To reference WS-TRUE-FALSE-FLAG in your program you just check to see if it is True or False.

The "decimal" data type is interesting to me due to it's versatility.  How often have you needed to define a field in Working-Storage to hold a number, but did not know how large the value might be?  Some would probably claim "poor design" but what if the size could not be predicted?

By using a "decimal" data type, you are defining a 128 bit variable to represent values within the range 1E-28 to 7.9E+28.  I believe the decimal data type was specifically created to deal with decimal values when dealing with money.

There are of course several restrictions on the usage of these new data types that you'll need to read up on.  You can find out the real nitty gritty in this online documentation.

So, if you revisit the code sample that Alex provided, you'll see a couple of things which may make a bit more sense now.  At least in the variable declarations portions anyway.



We'll get more into the other items another day once this soaks in.  ;)

Any questions?

2 comments:

  1. Hi,

    Decimal is interesting and I also believe it is a .net type specifically for money. I think it is the conceptual next step from the COM/vb6 64bit Currency type.

    However, let's not forget that MF COBOL supports similar decimal numerics using pic clauses - up to 38 decimal places - in both native and .net versions. Theses types have conceptually the same number of decimal places as the decimal type - but work at higher accuracy.

    For example, the .net 38 decimal place calculation engine works at 320 bits and the truncates to ensure that all calculations are completely correct all the time. After all, if you need 38 decimal places to work with money - the chances are you're working with a lot of money!

    - AJ

    PS Another great post - I love reading your stuff :)

    ReplyDelete
  2. OOPs - I said the MF types at 38 decimal places have the same number of significant places at .net decimal. That is not actually true - they have more! decimal is rated to 29 http://msdn.microsoft.com/en-us/library/364x0z75%28VS.80%29.aspx

    ReplyDelete