View previous topic :: View next topic
|
Author |
Message |
Suceender Kumar
New User
Joined: 10 Jan 2008 Posts: 29 Location: Chennai, India
|
|
|
|
Hi,
In COBOL copybook i have a field as below.
Code: |
05 I_CUST PIC S9(18)V USAGE COMP-3.
|
I am converting this copybook to SAS format as below.
Code: |
@064 I_CUST S370FPD10.1
|
Here is the input and output file.
Input
-------
Code: |
I_CUST
PS(18) (64-73)
-------------------
****************** T
+837118900720318901
+837118900720318901
+88119036179214201
+88119036179214201
+5271215533500495
+726119395100930701
|
Output
--------
Code: |
I_CUST
PS(18) (64-73)
-------------------
***************** T
+837118900720318720
+837118900720318720
+88119036179214192
+88119036179214192
+5271215533500495
+726119395100930560
|
I see some discrepancy in the output. Can anyone please help me?
Regards,
Suceender Kumar. |
|
Back to top |
|
|
Robert Sample
Global Moderator
Joined: 06 Jun 2008 Posts: 8696 Location: Dubuque, Iowa, USA
|
|
|
|
From the SAS 9.3 Companion for z/OS manual:
Quote: |
Representation of Integers
When processing in a z/OS environment, you should also be aware of the way that SAS stores integers. Like other numeric values, SAS maintains integer variables in 8-byte floating-point (real binary) representation. But under z/OS, outside of SAS, integer values are typically represented as 4-byte (fixed point) binary values using two's complement notation. SAS can read and write these values using informats and formats, but it does not process them internally in this form. SAS uses floating-point representation internally. |
and further under SAS document TS-654 Numeric Precision 101
Quote: |
72,057,594,037,927,936 |
is the largest value that can be stored exactly in SAS on a mainframe (the Unix and PC values are smaller). Your data is losing precision and you have several choices:
1) do not use numeric variables for your data
2) split the 18-digit packed decimal values into smaller values
3) accept that you cannot get precise values using SAS for your particular data and live with your results. |
|
Back to top |
|
|
Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
|
|
|
|
Who decided to store a "customer number" as packed-decimal :-), and 18 digits at that.
Whilst you may have saved in space along the way (presuming that that is the reason) you have lost out in all the processing you do on those "customer numbers".
Forgot to ask if there was an equivalent to Cobol's ARITH(EXTEND) for SAS. I guess not, else you'd have mentioned it Robert :-)
Without ARITH(EXTEND) Cobol only does 15 significant digit accuracy for COMP-2, so SAS is doing a little better there... |
|
Back to top |
|
|
Suceender Kumar
New User
Joined: 10 Jan 2008 Posts: 29 Location: Chennai, India
|
|
|
|
Thank you Robert. These values and copybook is extracted through UNLOAD utility from DB2, do some modification through SAS and then we load it back to the database through LOAD utility. Since this field is untouched in the SAS process we require the same value to be carried out while loading back to the database. Thanks for the insight!
Is there any alternate solution available in SAS like converting into some format while reading and reformatting it to its original value later? I tried splitting the variable into two but it didn’t work out. |
|
Back to top |
|
|
Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
|
|
|
|
As Robert has already suggested in his number 1), hold it as a text/character value.
As a numeric, SAS is not offering sufficient precision to do the size you need. |
|
Back to top |
|
|
Suceender Kumar
New User
Joined: 10 Jan 2008 Posts: 29 Location: Chennai, India
|
|
|
|
Hello Bill,
Just for an example i have named it as Customer ID but in real it has some other name. |
|
Back to top |
|
|
Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
|
|
|
|
Well, it's not a currency value, is it?
It doesn't matter what it is really called, it was probably a poor move to PACK it in the first place. You are not doing calculations with it, so, even if its content is numeric, it does not have to be defined as a numeric field. |
|
Back to top |
|
|
Suceender Kumar
New User
Joined: 10 Jan 2008 Posts: 29 Location: Chennai, India
|
|
|
|
Bill and Robert,
It worked fine when I changed it to char format. Thanks a lot! Still i need to check whether this char format from the output file is compatible in DB2 loading. Anyway thanks a lot! |
|
Back to top |
|
|
Robert Sample
Global Moderator
Joined: 06 Jun 2008 Posts: 8696 Location: Dubuque, Iowa, USA
|
|
|
|
Bill: SAS numeric variables have a maximum of 8 bytes and hence the value I quoted before is the absolute largest numeric value that can be precisely stored. I haven't looked yet to see if the newer z machines support 16-byte floating point values; even if they do, SAS has not yet been updated to allow them.
Suceender: use $CHAR10. in SAS to read the value. As long as you do not need the numeric value for anything, this will preserve the exact data in the field and DB2 should handle the data fine. You could read the data as
Code: |
@064 I_CUST1 PK5.
@069 I_CUST2 PD5. |
which would give you two variables that, together, can precisely represent the original value. Note the difference between PK and PD informats!
Side note: your COBOL declaration S9(18)V places the decimal point after the last digit (the V is optional in this case, by the way) whereas your SAS statement S370PD10.1 is placing the decimal point before the last digit. For the purposes of your original problem, not an issue -- but something to be aware of going forward. |
|
Back to top |
|
|
Suceender Kumar
New User
Joined: 10 Jan 2008 Posts: 29 Location: Chennai, India
|
|
|
|
Hello Robert,
Thanks for the detailed explanation. I used $CHAR10 and it worked fine. However when I used PK5 and PD5 split up the precise is maintained but the first 9 character has some other value. Please see the example below. Unless I use this field for computation I am fine with CHAR representation.
Input
--------
+733119436542372601
+733119436542372601
Output
---------
+542372601542372601
+542372601542372601 |
|
Back to top |
|
|
|