Page 1 of 2

Arithmetic operator: exponentiation (** or ^)

PostPosted: Tue Feb 14, 2012 3:25 am
by mendijur
Hello,

I have an input file with numeric fields like this:

00098302
00107503
00056000
00034501


The first 6 digits are prices, and the following 2 digits are the number of decimals. So previous records are interpreted as: 9.83, 1.075, 560, and 34.5

I'd like the output to be something like the following:

0009.83
001.075
0000560
00034.5


I wonder whether DFSORT has an exponentiation arithmetic operator like Cobol's **, or Visual Basic's ^, or a funxtion like SQL's power().

Thanks,
Regards.

Re: Arithmetic operator: exponentiation (** or ^)

PostPosted: Tue Feb 14, 2012 3:32 am
by BillyBoyo
Why would you need any mathematical functions at all? You could use an appropriate edit mask depending on the number of decimal places.

Re: Arithmetic operator: exponentiation (** or ^)

PostPosted: Tue Feb 14, 2012 3:43 am
by skolusu
mendijur,

Use the following DFSORT JCL which will give you the desired results.
//STEP0100 EXEC PGM=SORT                                         
//SYSOUT   DD SYSOUT=*                                           
//SORTIN   DD *                                                   
----+----1----+----2----+----3----+----4----+----5----+----6----+-
00098302                                                         
00107503                                                         
00056000                                                         
00034501                                                         
//SORTOUT  DD SYSOUT=*                                           
//SYSIN    DD *                                                   
  SORT FIELDS=COPY                                               
  INREC IFTHEN=(WHEN=(7,2,ZD,EQ,0),BUILD=(1,6,ZD,EDIT=(TTTTTTT))),
        IFTHEN=(WHEN=(7,2,ZD,EQ,1),BUILD=(1,6,ZD,EDIT=(TTTTT.T))),
        IFTHEN=(WHEN=(7,2,ZD,EQ,2),BUILD=(1,6,ZD,EDIT=(TTTT.TT))),
        IFTHEN=(WHEN=(7,2,ZD,EQ,3),BUILD=(1,6,ZD,EDIT=(TTT.TTT)))
//*

Re: Arithmetic operator: exponentiation (** or ^)

PostPosted: Thu Feb 16, 2012 3:50 am
by mendijur
I'm sorry I didn't explain myself well.

I'd the exponentiation operator because the input file has several numeric fields: number of shares and price. I need to calculate the net cash (number of shares x price). The price field's format is as I earlier tried to explain: 8 digits: 6 first digits is the numeric value, and the following 2 digits are the number of decimals. So I'd like to have an exponentiation operator to calculate cash as SHARES x PRICE / (10 ** # DECIMALS) and write this field edited in the output file from DFSORT.

Regards.

Re: Arithmetic operator: exponentiation (** or ^)

PostPosted: Thu Feb 16, 2012 4:23 am
by skolusu
mendijur,

It can be done. Answer all of the questions

1. What is the LRECL and RECFM of the input file?
2. What is the position and format of share field?
3. What is the position and format of the price field?
4. What is the LRECL and RECFM of the output file?
5. What is the position in the output file that you want the result of SHARE X PRICE ? and what is the format of it?
6. Show us a sample of Input and desired output.

Re: Arithmetic operator: exponentiation (** or ^)

PostPosted: Thu Feb 16, 2012 4:31 am
by enrico-sorichetti
do You care about the result or about the process ?
Did You run the snippet posted by Kolusu ?
it gives exactly the output You asked for, the last <explanation> just confuses things !

here is another snippet to show You also the SHARES*PRICES calculations

 000005 //ICE     EXEC PGM=SORT                                                 
 000006 //SYSPRINT  DD SYSOUT=*                                                 
 000007 //SYSOUT    DD SYSOUT=*                                                 
 000008 //*                                                                     
 000009 //SYMNAMES  DD *                                                       
 000010 PRICES,01,6,ZD                                                         
 000011 DIGITS,07,2,ZD                                                         
 000012 SHARES,10,5,ZD                                                         
 000013 VALUES,20,8,ZD                                                         
 000014 //SORTIN    DD *                                                       
 000015 00098302 00010                                                         
 000016 00107503 00011                                                         
 000017 00056000 00012                                                         
 000018 00034501 00013                                                         
 000019 //SORTOUT   DD SYSOUT=*,                                               
 000020 //             DCB=(RECFM=FB,LRECL=80)                                 
 000021 //SYSIN     DD *                                                       
 000022   SORT   FIELDS=COPY                                                   
 000023   INREC OVERLAY=(20:PRICES,MUL,SHARES,TO=ZD,LENGTH=8)                   
 000024   OUTREC IFTHEN=(WHEN=(DIGITS,EQ,0),                                   
 000025                  OVERLAY=(30:PRICES,EDIT=(TTTTTTT),                     
 000026                           40:VALUES,EDIT=(TTTTTTTTTTT))),               
 000027          IFTHEN=(WHEN=(DIGITS,EQ,1),                                   
 000028                  OVERLAY=(30:PRICES,EDIT=(TTTTT.T),                     
 000029                           40:VALUES,EDIT=(TTTTTTTTT.T))),               
 000030          IFTHEN=(WHEN=(DIGITS,EQ,2),                                   
 000031                  OVERLAY=(30:PRICES,EDIT=(TTTT.TT),                     
 000032                           40:VALUES,EDIT=(TTTTTTTT.TT))),               
 000033          IFTHEN=(WHEN=(DIGITS,EQ,3),                                   
 000034                  OVERLAY=(30:PRICES,EDIT=(TTT.TTT),                     
 000035                           40:VALUES,EDIT=(TTTTTTT.TTT)))               

********************************* TOP OF DATA **********************************
00098302 00010     00009830  0009.83   00000098.30                             
00107503 00011     00011825  001.075   0000011.825                             
00056000 00012     00006720  0000560   00000006720                             
00034501 00013     00004485  00034.5   000000448.5                             
******************************** BOTTOM OF DATA ********************************


I added at pos 10,5 the number of shares
the output shows the raw multiplication result the price edited the total value edited
if this is not what You are asking for
then You will have to do a better job in explaining,
and.... if You stick to doing using exponentiation, You will have to resort to a different tool

as usual... Kolusu might show a better solution

Re: Arithmetic operator: exponentiation (** or ^)

PostPosted: Thu Feb 16, 2012 5:37 am
by Frank Yaeger
So I'd like to have an exponentiation operator


DFSORT does NOT have an exponentiation operator.

Re: Arithmetic operator: exponentiation (** or ^)

PostPosted: Tue Feb 21, 2012 8:13 pm
by mendijur
Sorry for being late in giving signs... I've been very busy these days.

Many many thanks to Kolusu, Enrico and Frank for your replies.

I understand the approaches of Kolusu and Enrico. The thing's that the number of decimals is unknown. What is known is that the field containing the number of decimals is 2-digit long. So in theory the range for the number of decimals is 00 to 99, high values being improbable. According to Kolusu's and Enrico's approach I'd have to forsee the different possibilities of decimals using IFTHEN statements, which for a small number of cases might be acceptable, but not to cope with any possibility.

I think the cleanest approach (thinking about ease of maintainability of the software module) in this sccenario will be to make the calculations in a program, using the language-supplied exponentiation operator.

Many thanks to all of you.
Kindest regards.

Re: Arithmetic operator: exponentiation (** or ^)

PostPosted: Tue Feb 21, 2012 8:36 pm
by enrico-sorichetti
So in theory the range for the number of decimals is 00 to 99, high values being improbable.

horse manure ...
reread Your favorite programming language manuals,
find out the limits for number representation and meditate and that will be ...
quoting from some COBOL manual
... the maximum size of each operand is 18 <decimal>digits.
If the ARITH(EXTEND) compiler option is in effect, the maximum size of each operand is 31 <decimal> digits.

<decimal> as number base representation

as far as the sample posted since the input numbers are 6 digits, at most it is expected to have at most 6 decimal digits

from my experience in the bank domain the most decimals ( after the dot/comma) digits I have seen are
6 for <internal> computation and 4 for display ( a few specific applications )
but usually 4 and 2 are most common.

so You should have at most 6 IFTHEN

on the other side since You complain about the solutions provided
probably the requirement was badly described

Re: Arithmetic operator: exponentiation (** or ^)

PostPosted: Tue Feb 21, 2012 9:10 pm
by BillyBoyo
No. You have a maximum number of numeric digits. System-applied, reflected by DFSORT (and everything else).

If you have your own "floating point" number for the prices (seems weird, but you say so) then keep it as a fkiating point and report it in "scientifc notation". 0.1234 (or 1.234) X 10 to the power of <number of places>.

As it is, I'd be extremely surprised if you have even nine decimals. Whoever wrote the business requirement will know for sure.

You have also ignored Kolusu saying that it is possible, if you answer all his questions. Instead you want to stick to using "exponentiation" for a seemingly bogus reason.

I'm all for the "cleanest" approach. What do you want to do, an E35 or abandon the sort altogether? Or add something on afterwards, or before?

If you do not have other need of SORT for the task, OK, another program is simple. If you do have need of SORT then you risk complicating the process to make it simple.

Note: And I agree with enrico. I was just interrupted while writing.