title: How can I convert a Cobol COMP field output to readable decimal in C#?
body: <p>In converting a cobol program to C#, I encountered COMP:</p>
  
  <pre><code>03  Var1                     PIC X(4).
  03  Var2                     PIC X(3).
  03  Var3                     PIC X(3).
  03  Var4                     PIC X(4).
  03  Var5                     PIC X(16).
  03  Var6                     PIC X(4).
  03  Var7                     PIC X(2).
  03  Var8                     PIC X.
  03  Var9                     PIC X(4).
  03  Var10                    PIC X(16).
  03  Var11                    PIC S9(7)V9(2) COMP.
  03  Var12                    PIC S9(7)V9(2) COMP.
  03  Var13                    PIC S9(7)V9(2) COMP.
  03  Var14                    PIC S9(7)V9(2) COMP.
  03  Var15                    PIC S9(7)V9(2) COMP.
  03  Var16                    PIC S9(7)V9(2) COMP.
  03  Var17                    PIC S9(7)V9(2) COMP.
  03  Var18                    PIC S9(7)V9(2) COMP.
  03  Var19                    PIC S9(7)V9(2) COMP.
  03  Var20                    PIC S9(7)V9(2) COMP.
  03  Var21                    PIC S9(7)V9(2) COMP.
  03  Var22                    PIC S9(7)V9(2) COMP.
  03  Var23                    PIC S9(7)V9(2) COMP.
  03  Var24                    PIC S9(7)V9(2) COMP.
  </code></pre>
  
  <p>I've spent several hours looking into COMP. Most searches yield something about COMP-3 or mention that COMP is a binary conversion. However, the cobol program's COMP output is the non-COMP fields followed by (between the parentheses):</p>
  
  <p><code>(        F  ”                    "                   )</code> </p>
  
  <p>while the actual values are all 0.00, except that var13 is 64.70</p>
  
  <p>NOTE: these are the values copied from Notepad++. Also, note that I know very little about cobol.</p>
  
  <p><strong>How can I convert from COMP to decimal?</strong> Ideally, I could also convert decimal to COMP as well, as I need to put things back into the same format.</p>
  
  <p>I have tried reading the data in as binary with: </p>
  
  <pre><code>public static void ReadBinaryFile(string directoryString)
      {
          using (BinaryReader reader = new BinaryReader(File.Open(directoryString, FileMode.Open)))
          {
              string myString = Encoding.ASCII.GetString(reader.ReadBytes(113));
              Console.WriteLine(myString);
          }
      }
  </code></pre>
  
  <hr>
  
  <p><strong>EDIT: On the right track</strong></p>
  
  <p>Thanks to @piet.t and @jdweng for the help.</p>
  
  <p>While there is still an issue with this test code, this should help anyone in my position with their solution:</p>
  
  <pre><code>public static void ReadBinaryFile(string directoryString)
      {
          using (BinaryReader reader = new BinaryReader(File.Open(directoryString, FileMode.Open)))
          {
              string asciiPortion = Encoding.ASCII.GetString(reader.ReadBytes(57)); // Read the non-comp values
  
              Console.Write(asciiPortion); // Test the ascii portion 
  
              Console.WriteLine("var11: " + reader.ReadInt32());
              Console.WriteLine("var12: " + reader.ReadInt32());
              Console.WriteLine("var13: " + reader.ReadInt32());
              Console.WriteLine("var14: " + reader.ReadInt32());
              Console.WriteLine("var15: " + reader.ReadInt32());
              Console.WriteLine("var16: " + reader.ReadInt32());
              Console.WriteLine("var17: " + reader.ReadInt32());
              Console.WriteLine("var18: " + reader.ReadInt32());
              Console.WriteLine("var19: " + reader.ReadInt32());
              Console.WriteLine("var20: " + reader.ReadInt32());
              Console.WriteLine("var21: " + reader.ReadInt32());
              Console.WriteLine("var22: " + reader.ReadInt32());
              Console.WriteLine("var23: " + reader.ReadInt32());
              Console.WriteLine("var24: " + reader.ReadInt32());
          }
      }
  </code></pre>
  
  <hr>
  
  <p><strong>EDIT 2: Trying to find the issue</strong></p>
  
  <p>Issue: every value appears to be followed by some garbage value which is printed as the next int32.</p>
  
  <p>Actual values:</p>
  
  <pre><code>var11 = var12 = 0.00
  var13 = 58.90
  var14 = 0.00
  var15 = -0.14
  var16 = 0.00
  var17 = var18 = var19 = var20 = 0.00
  var21 = var22 = var23 = var24 = 0.00
  </code></pre>
  
  <p>Output (with padding):</p>
  
  <pre><code>Var11:     0  HEX: 00000000  BIN: 00000000000000000000000000000000
  Var12:     0  HEX: 00000000  BIN: 00000000000000000000000000000000
  Var13:  5890  HEX: 00001702  BIN: 00000000000000000001011100000010
  Var14:   368  HEX: 00000170  BIN: 00000000000000000000000101110000
  Var15:   -14  HEX: FFFFFFF2  BIN: 11111111111111111111111111110010
  Var16:    -1  HEX: FFFFFFFF  BIN: 11111111111111111111111111111111
  Var17:     0  HEX: 00000000  BIN: 00000000000000000000000000000000
  Var18:     0  HEX: 00000000  BIN: 00000000000000000000000000000000
  Var19:     0  HEX: 00000000  BIN: 00000000000000000000000000000000
  Var20:     0  HEX: 00000000  BIN: 00000000000000000000000000000000
  Var21:     0  HEX: 00000000  BIN: 00000000000000000000000000000000
  Var22:     0  HEX: 00000000  BIN: 00000000000000000000000000000000
  Var23:     0  HEX: 00000000  BIN: 00000000000000000000000000000000
  Var24:     0  HEX: 00000000  BIN: 00000000000000000000000000000000
  </code></pre>
  
  <p>Notepad++ (Copied) Representation:</p>
  
  <pre><code>          p  òÿÿÿÿÿÿÿ                                
  </code></pre>
  
  <p>Notepad++ (Visual) Representation:</p>
  
  <pre><code>[NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL][STX][ETB][NUL][NUL]p[SOH]
  [NUL][NUL]òÿÿÿÿÿÿÿ[NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL]
  [NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL]
  [NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL][LF]
  </code></pre>
  
  <hr>
  
  <p><strong>EDIT 3: Solution!</strong></p>
  
  <p>@piet.t had it all right. Thanks for a useful answer to my first question! The issue was something specific to the cobol program. I was led to believe Var14 was always 0, but:</p>
  
  <pre><code>Var14 = SomeCalculationIHadNoIdeaAbout(Var13, SomeOtherNumber);
  </code></pre>
  
  <p>I used <a href="https://stackoverflow.com/questions/31921354/convert-cobol-comp-data-to-ascii">RecordEdit</a> to tweak the data more easily (Warning: the program is a little strange in places) and noticed an odd trend in the "garbage" values. </p>
  
  <p>The real solution to my problem is the code in the first EDIT, which I made days ago :/.</p>
  
  <p>NOTE: I also had to consume a line feed character, which I did not put in that code. To do that, just add another <code>reader.ReadBytes(1);</code>.</p>
  
  <p>NOTE 2: You may need to look into <a href="https://stackoverflow.com/questions/2858202/how-to-convert-from-ebcdic-to-ascii-in-c-net">EBDCDIC</a> and/or <a href="https://stackoverflow.com/questions/8241060/how-to-get-little-endian-data-from-big-endian-in-c-sharp-using-bitconverter-toin">Endianness</a>, which may make your solution a bit more difficult than mine.</p>