View previous topic :: :: View next topic

Author 
Message 
Abhinav Chandra
New User
Joined: 13 Oct 2012 Posts: 29 Location: India




Need help in resolving SOCC abend for below mentioned piece of code. All the variables in the statements below are COMP2. 
Code: 
COMPUTE NEWINTRATE
= INTERESTRATE
 (FUNDVALUE  TARGETVALUE)
* (INTERESTRATE  PREVINTRATE)
/ (FUNDVALUE  PREVFUNDVALUE). 
On the further analysis this statement was broken in the smaller segments to find the actual cause of the issue. So the statements below are the same as statement above, just our approach is broken in pieces.
Code: 
COMPUTE VALUE1 = FUNDVALUE  PREVFUNDVALUE
COMPUTE VALUE2 = INTERESTRATE  PREVINTRATE
COMPUTE VALUE3 = FUNDVALUE  TARGETVALUE
COMPUTE VALUE4 = VALUE2 / VALUE1
COMPUTE VALUE5 = VALUE3 * VALUE4
COMPUTE NEWINTRATE = INTERESTRATE  VALUE5 
It was found that the statement 'COMPUTE VALUE5 = VALUE3 * VALUE4' is causing the S0CC. And based on the displays at time of the abend, here are the values for these variables.
Code: 
FUNDVALUE: .00000000000000000E 00
TARGETVALUE: .13484000000000000E 03
INTERESTRATE: .76960903639477748E 00
PREVINTRATE: .90367094297093048E 00
PREVFUNDVALUE: .51872912558109839E75 
So what will be the solution to this final piece of calculation which is causing S0CC. Any help on this would be highly appreciated. 

Back to top 




Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7312 Location: Inside the Matrix




What do you have for compiler option ARITH?
Why are all the values COMP2?
What sort of valid ranges do you have for the figures? 

Back to top 


Abhinav Chandra
New User
Joined: 13 Oct 2012 Posts: 29 Location: India




Please look for my answers on your above queries.
1. What do you have for compiler option ARITH?
This is I used to find the line thats abending..
or basically for the last run.. this does not has SSRANGE
//COMPILE EXEC PGM=IGYCRCTL,
// PARM=('LIB,RENT,DATA(31),OFFSET',
// 'BUF(32K),OPT,MAP,TRUNC(STD)',
// 'NODYNAM,NOADV,NOTERM',
// 'NUMPROC(NOPFD)',
// 'NOLIST'),
// COND=(4,LT,PRECOMP)
Did compiling it with ARITH will resolve the SOCC ?
2. Why are all the values COMP2?
Its already defined from a very long time and was performing well earlier.
3. What sort of valid ranges do you have for the figures?
I didn't get you on this, can you please explain what you are looking for. 

Back to top 


Akatsukami
Global Moderator
Joined: 03 Oct 2009 Posts: 1789 Location: Bloomington, IL




Abhinav Chandra wrote: 
3. What sort of valid ranges do you have for the figures?
I didn't get you on this, can you please explain what you are looking for. 
A S0CC is an exponent overflow. PREVFUNDVALUE has a value of .51872912558109839E75. Does not that value seem of dubious validity to you? 

Back to top 


Abhinav Chandra
New User
Joined: 13 Oct 2012 Posts: 29 Location: India




Tried running the job after compiling it with compiler option ARITH(EXTEND), but still getting the same error again. 

Back to top 


Akatsukami
Global Moderator
Joined: 03 Oct 2009 Posts: 1789 Location: Bloomington, IL




Tell me, Abhinavkun, what currency is the fund in that you would expect its previous value to be less than 10^75 unit? Or do you think that that value is evidence that that variable wasn't initialized, was overwritten by nonfloatingpoint data, or for some other reason has invalid garbage in it? 

Back to top 


Abhinav Chandra
New User
Joined: 13 Oct 2012 Posts: 29 Location: India




No Akatsukami, the value for the field PREVFUNDVALUE: .51872912558109839E75 is perfectly fine 

Back to top 


Akatsukami
Global Moderator
Joined: 03 Oct 2009 Posts: 1789 Location: Bloomington, IL




Abhinav Chandra wrote: 
No Akatsukami, the value for the field PREVFUNDVALUE: .51872912558109839E75 is perfectly fine 
Well, remind me never to entrust so much as a yoctocent to whatever company you're programming for 

Back to top 


Robert Sample
Global Moderator
Joined: 06 Jun 2008 Posts: 8562 Location: Dubuque, Iowa, USA




You have a fund value where 75 zeroes between the decimal point and the first digit is acceptable? I think the first problem is that you have no clue about what valid values for your data SHOULD be  especially since 25 digits is MORE than enough for any currency currently in use in the world, yet you are claiming 50 more digits are valid data for you.
Show us code initializing (or setting) each of the variables in your equation before the execution of the statements comprising the equation. 

Back to top 


Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7312 Location: Inside the Matrix




You PREVFUNDVALUE is negative and absolutely tiny. Miniscule. Unless you apply it to massively enormous values it is effectively zero, just not quite. If you were to divide it by 10 or so, you'd have a number which COBOL cannot support. You do more than divide it by 10, so you get the S0CC.
It may have been working for years, or decades, but the S0CC could probably have happened at any time  maybe.
You have to determine why such an absurdly small value came about.
Why I asked about the ranges that your values may have, was to determine whether floatingpoint numbers are necessary, and whether they have to be COMP2, and whether you need the extended precision which ARITH(COMPAT) would give you.
Someone needs to analyse the original business requirement and see how it should be implemented in COBOL. I have never used COMP1 or COMP2 for a business calculation. Your calculation is not a complex one, so you'd only require COMP1 or COMP2 if the values you are dealing with require a precision which in total is greater than COMP3 allows  meaning for instance you have to cover 18 digits in front of the decimal place and at least one digit after the decima place (or any combination in total where there are more than 18 digits).
I cannot believe that you have a "fund" in any currency which requires more than 18 significant digits.
If you were only using ARITH(COMPAT) (for years) you should be aware that the precision in all those calculations is limited to a maximum of 15 siginificant digits.
If you in reality don't need more than 15 significant digits, then you will be OK. If you did need more than 15 significant digits, then you have some nasty problemdetermination coming up.
You got a S0CC because your value exceeded the size that COBOL can support. For your calculation, there can be nothing correct about that, even if the large figure is a cumulative effect of imprecise floatingpoint calculations.
Find the business requirement. Find the minimum and maximum value (including positive and negative) of all component values. Decide upon a USAGE (and PICTURE if necessary) based on your findings. If you still decide COMP2 is the thing for you 1) I'd be surprised 2) you've got some bulletproofing and evaluation and all that type of stuff.
At least you're not doing lots of these calculations. They're deadly slow, and are going to get slower if you "need" precision and therefore ARITH(EXTEND). 

Back to top 


Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7312 Location: Inside the Matrix




Akatsukami may have made a good shot. Unless your source fields are COMP2 on file/DB/interface then the absurdly small value has been arrived at in your program/system. Whilst possible to get to such a small value through many erroneous manipulations, simply trashing it at some point would be by far the simplest  so most likely  way to do it.
So you might have absurd calculations (not your doing, someone in the past) and a bug.
You (or someone in your organisation) are going to have to spend a lot of time and be exceedingly careful to get this fixed properly. It will likely involve accountants and auditors.
Bear in mind, even when you find the bug (if there is one), you can't just use ARITH(EXTEND) if you need the extra precision without the impactanalysis into the previous calculations over whatever period.
If you don't need the precision, then you (very probably) don't need floatingpoint. If the reason for floatingpoint is a source value, with a total range of 18 siginifcant digts or fewer, then it can be/should be MOVEd to a packeddecimal, processed, and the result MOVEd back for the output.
A big clue as to whether floatingpoint is needed is the source fields and any "reported" (print or screen) values.
C/C++/JAVA may be, stupidly, giving you a "double". If this is so, and it is just to have a decimal part, then MOVE to packed, process, MOVE back.
Maybe there are reasons for the calulation requiring COMP2, but I can't think of any genuine ones, looking at the calculation itself and the datanames. 

Back to top 


Akatsukami
Global Moderator
Joined: 03 Oct 2009 Posts: 1789 Location: Bloomington, IL




Bill Woodger wrote: 
Akatsukami may have made a good shot. 
"May"? 

Back to top 


Abhinav Chandra
New User
Joined: 13 Oct 2012 Posts: 29 Location: India




Thanks alot for all your valuable thoughts and suggestions. 

Back to top 


jerryte
Active User
Joined: 29 Oct 2010 Posts: 195 Location: Toronto, ON, Canada




I suggest to add logic prior to the calculation
Code: 
IF PREVFUNDVALUE < 1.0E20 THEN
MOVE ZERO TO PREVFUNDVALUE
ENDIF 
This will put an actual zero value into the variable instead of an almost zero value. Choose an exponent that represents for you a zero value. "20" is being generous
Disclaimer: I have not tested it but I hope you get the general idea. 

Back to top 


