$SET SOURCEFORMAT"FREE" identificationdivision
* program-id. CALC
* author. Robert Wagner
* date-written. 07/29/04
* Huge number function library.
* Parses formula out of a string.
* Runs three ways:
* From command line -- type in formula
* Call CALCPARS -- to parse andevaluate formula
* Call CALCxxxx low-level functions
*
* Negative numbers are nines complement.
* The left half contains the 'whole number'and the right half contains the
* fraction.
*
* Note that everything isrelativeto the sizeof'huge' below.
* The program would read better if I could equate
* 'mid'to'length of huge / 2'. I couldn't find a way in Cobol 85.
. linkagesection
. 01 a huge
. 01 b huge
. 01 c huge
. 01 input-string
. 05 input-byte occurs 128 indexed x-in pic x(01)
* Compiler insists on this USING. There areno parms to main.
. PROCEDUREDIVISIONusing a, b, c, input-string. move low-values to typein performuntil typein equaltospaces display'Enter problem' accept typein move zeros to x, y, z
call'CALCPARS'using x, y, z, typein
display'the answer is: 'withnoadvancing call'DISPC'using x, y, z end-perform stoprun
. entry'CALCPARS'using a, b, c, input-string. move a to x move b to y move zeros to a, b, c move 1 to sp move zeros to stack-number (1) move'+'to stack-operation (1) set x-in to 1 perform one-word until x-in greaterthan 128 if sp notequalto 1 display'too many left parens' perform do-operation until sp = 1 end-if move stack-number (1) to c
goback
. one-word. evaluate input-byte (x-in) when = '+'or'-'or'*'or'/'or'^'or'!' move input-byte (x-in) to stack-operation (sp) if input-byte (x-in) equalto'!' perform do-operation movespaceto stack-operation (sp) end-if when'0' thru '9' when'.' perform pickup-number perform process-number when'(' perform bump-sp move zeros to stack-number (sp) move'+'to stack-operation (sp) when')' perform do-operation when'a' move x to b perform process-number when'b' move y to b perform process-number whenspace continue whenother set i to x-in display'invalid input ' input-byte (x-in) ' col ' i end-evaluate set x-in upby 1
. pickup-number. move zeros to b compute p = lengthof huge / 2 performuntil (input-byte (x-in) less'0'orgreater'9') and
input-byte (x-in) notequalto'.' if input-byte (x-in) equalto'.' compute p = (lengthof huge / 2) + 1 else if p equalto (lengthof huge / 2) call'CALCSHL'using a, b, c move input-byte (x-in) to a-digit in b (lengthof huge / 2) else move input-byte (x-in) to a-digit in b (p) add 1 to p end-if end-if set x-in upby 1 end-perform set x-in downby 1
. process-number. perform bump-sp move b to stack-number (sp) perform do-operation
. do-operation. if debug-mode if stack-operation (sp) notequalto'!' perform dec-sp end-if move stack-number (sp) to c perform display-c display stack-operation (sp) if stack-operation (sp) notequalto'!' perform bump-sp move stack-number (sp) to c perform display-c end-if end-if
move stack-number (sp) to b if stack-operation (sp) notequalto'!' perform dec-sp move stack-number (sp) to a end-if evaluate stack-operation (sp) when'+' call'CALCADD'using a, b, c when'-' call'CALCSUB'using a, b, c when '*' call'CALCMUL'using a, b, c when'/' call'CALCDIV'using a, b, c when'^' call'CALCEXP'using a, b, c when'!' call'CALCFAC'using a, b, c whenother move b to c end-evaluate move c to stack-number (sp)
if debug-mode display'=' perform display-c end-if
. bump-sp. if sp lessthan 10 add 1 to sp else display'stack overflow' end-if
. dec-sp. if sp greaterthan 1 subtract 1 from sp else display'too many right parens' end-if
. display-c. if a-digit in c (1) equalto 9 call'CALCNEG'using a, b, c display'-'withnoadvancing end-if performvarying i from 1 by 1 until
a-digit in c (i) not = zeroor i > 99 continue end-perform performvarying i from i by 1 until i > ((lengthof huge / 2) + 20) or
(i equalto ((lengthof huge / 2) + 1) and
c((lengthof huge / 2) + 1:lengthof huge / 2) equaltozero) display a-digit in c (i) withnoadvancing if i equalto (lengthof huge / 2) display'.'withnoadvancing end-if end-perform displayspace
. end-calcpars
* Begin calchuge.
. entry'CALCADD'using a, b, c. perform compute-a-plus-b goback
. entry'CALCSUB'using a, b, c. perform compute-a-minus-b goback
. entry'CALCMUL'using a, b, c. perform compute-a-times-b goback
. entry'CALCDIV'using a, b, c. perform compute-a-divided-by-b goback
. entry'CALCEXP'using a, b, c. if b(1:(lengthof huge / 2) - 2) equaltozeroand
b((lengthof huge / 2) + 1:lengthof huge / 2) equaltozero perform compute-a-ipower-b else perform compute-a-power-b end-if goback
. entry'CALCFAC'using a, b, c. perform compute-b-factorial goback
. entry'CALCNEG'using a, b, c. perform flip-sign-c goback
. entry'CALCSHR'using a, b, c. perform shift-b-right goback
. entry'CALCSHL'using a, b, c. perform shift-b-left goback
. entry'DISPC'using a, b, c. perform display-c goback
. compute-a-plus-b. movezeroto overflow-digit if 9 not = a-digit in b (1) and a-digit in a (1) move 0 to overflow-digit perform add-operation else if 9 = a-digit in b (1) and a-digit in a (1) move 1 to overflow-digit perform add-operation else perform flip-sign-b perform compute-a-minus-b end-if
. add-operation. performvarying i fromlengthof huge by -1 until i lessthan 1 compute temp-s =
a-digit in a (i) + a-digit in b (i) + overflow-digit if temp-s lessthan 10 move temp-s to a-digit in c (i) move 0 to overflow-digit else subtract 10 from temp-s giving a-digit in c (i) move 1 to overflow-digit end-if end-perform
. compute-a-minus-b. movezeroto overflow-digit if b greaterthan a move 1 to overflow-digit end-if performvarying i fromlengthof huge by -1 until i lessthan 1 compute temp-s =
a-digit in a (i) - a-digit in b (i) - overflow-digit if temp-s lessthanzero add 10 to temp-s giving a-digit in c (i) move 1 to overflow-digit else move temp-s to a-digit in c (i) move 0 to overflow-digit end-if end-perform
. compute-a-times-b. perform normalize-sign-in move zeros to d performvarying i fromlengthof huge by -1 until i lessthan 1 if a-digit in b (i) notequaltozero compute k = i + (lengthof huge / 2) performvarying j fromlengthof huge by -1 until j lessthan 1 if a-digit in a (j) notequaltozeroand
k notless 1 andnotgreaterlengthof huge compute two-digits =
a-digit in a (j) * a-digit in b (i) perform add-two-digits end-if subtract 1 from k end-perform end-if end-perform move d to c perform normalize-sign-out
. compute-a-divided-by-b. perform normalize-sign-in compute k = lengthof huge / 2 performuntil b notlessthan a or k = 1 perform shift-b-left subtract 1 from k end-perform move zeros to d performuntil k > lengthof huge performuntil b greaterthan a or b = zeros move 1 to two-digits perform add-two-digits perform compute-a-minus-b move c to a end-perform perform shift-b-right add 1 to k end-perform move d to c perform normalize-sign-out
. compute-a-power-b.
* Computing a^b move a to temp-a move b to temp-b if a-digit in a (1) equalto 9 or a equaltozero movezeroto c exit paragraph end-if
* Get the exponent by repeatedly dividing by e movezeroto e, exponent move'27182818284590452353602874'to e(lengthof huge / 2:26) performuntil temp-a notgreaterthan e move temp-a to a move e to b perform compute-a-divided-by-b move c to temp-a move exponent to a movezeroto b move 1 to a-digit in b (lengthof huge / 2) perform compute-a-plus-b move c to exponent end-perform
* Compute base e logarithm of the mantissa
* ln(x) = performvarying t from 1 by 2 until delta = zeroor t > 90
* compute ln = ln + ((2 / t) * (((x - 1) / (x + 1)) ^ t))
* where 0 < x < e move temp-a to a movezeroto b move 1 to a-digit in b (lengthof huge / 2) perform compute-a-minus-b move c to temp-2 perform compute-a-plus-b move temp-2 to a move c to b perform compute-a-divided-by-b move c to temp-2 *> save (x - 1) / (x + 1) movezeroto temp-3 moveall'1'to b performvarying term from 1 by 2 until
b(1:(lengthof huge / 2) + 16) = zeroor term > 90 or
b(1:(lengthof huge / 2) + 16) = all'9' movezeroto a, b move 2 to a-digit in a (lengthof huge / 2) move term to b((lengthof huge / 2) - 1:2) perform compute-a-divided-by-b move c to temp-1 move temp-2 to a movezeroto b move term to b((lengthof huge / 2) - 1:2) perform compute-a-ipower-b move temp-1 to a move c to b perform compute-a-times-b move temp-3 to a move c to b perform compute-a-plus-b move c to temp-3 end-perform
* Add the exponent giving ln(a) move c to a move exponent to b perform compute-a-plus-b
* Multiplyby b move c to a move temp-b to b perform compute-a-times-b move c to temp-a
* e^x = performvarying t from 1 by 1 until delta = zeroor t > 90
* compute exp = exp + ((x ^ t) / t!)
* add 1 to exp
* Note that ln(a) will be negativewhen a < 1. In that case, this is
* an alternating series because n^t will be negative half the time. movezeroto b move 1 to a-digit in b (lengthof huge / 2) move b to temp-3 performvarying term from 1 by 1 until
b(1:(lengthof huge / 2) + 16) = zeroor term > 90 move temp-a to a movezeroto b move term to b((lengthof huge / 2) - 1:2) perform compute-a-ipower-b move c to temp-1 movezeroto b move term to b((lengthof huge / 2) - 1:2) perform compute-b-factorial move temp-1 to a move c to b perform compute-a-divided-by-b move temp-3 to a move c to b perform compute-a-plus-b move c to temp-3 end-perform
* Discard meaningless digits if c ((lengthof huge / 2) + 17:(lengthof huge / 2) - 16) notequaltozero move c to a movezeroto b move 5 to a-digit in b ((lengthof huge / 2) + 17) perform compute-a-plus-b movezeroto c((lengthof huge / 2) + 17:(lengthof huge / 2) - 16) end-if if c((lengthof huge / 2) + 1:6) equaltozeroand
c(1:(lengthof huge / 2)) notequaltozero movezeroto c((lengthof huge / 2) + 7:(lengthof huge / 2) - 6) end-if
* Integer exponent 1-99
. compute-a-ipower-b. move b((lengthof huge / 2) - 1:2) to two-digits move two-digits to power move zeros to b move 1 to a-digit in b (lengthof huge / 2) perform power times perform compute-a-times-b move c to b end-perform if c((lengthof huge / 2) + 1:10) equaltozeroand
c(1:(lengthof huge / 2)) notequaltozero movezeroto c((lengthof huge / 2) + 11:(lengthof huge / 2) - 10) end-if
. compute-b-factorial. move b((lengthof huge / 2) - 1:2) to two-digits move two-digits to power move zeros to a, b move 1 to a-digit in a (lengthof huge / 2),
a-digit in b (lengthof huge / 2) performvarying factorial from 1 by 1 until factorial > power move factorial to two-digits move two-digits to b((lengthof huge / 2) - 1:2) perform compute-a-times-b move c to a end-perform
. flip-sign-a. inspect a converting'0123456789' to'9876543210'
. flip-sign-b. inspect b converting'0123456789' to'9876543210'
. flip-sign-c. inspect c converting'0123456789' to'9876543210'
. shift-b-right. move b(1:lengthof huge - 1) to shifter(2:lengthof huge - 1) movezeroto shifter(1:1) move shifter to b
. shift-b-left. move b(2:lengthof huge - 1) to shifter(1:lengthof huge - 1) movezeroto shifter(lengthof huge:1) move shifter to b
. add-two-digits. move k to l performuntil two-digits = zeroor l < 1 add a-digit in d (l) to two-digits move digit-2 to a-digit in d (l) move digit-1 to digit-2 move 0 to digit-1 subtract 1 from l end-perform
. normalize-sign-in. movezeroto sign-count if a-digit in a (1) equalto 9 add 1 to sign-count perform flip-sign-a end-if if a-digit in b (1) equalto 9 add 1 to sign-count perform flip-sign-b end-if
. normalize-sign-out. if sign-count equalto 1 perform flip-sign-c end-if
[ GotoTopofPage ]
COBOL NuTrak Ad
Local COBOL User Groups COBOL User Group Check out the list of local COBOL user groups from around the world and join a user group near you.
Callfor User Group Leaders! COBOL User Groups Get Involved! We are looking for user group leaders to help organize and coordinate a local COBOL user group.
Join COBUG! COBOL User Groups Become a part of the COBUG community today. Join Now ...
COBOL Forums COBOL Forum Try our forums for help!
Let the COBUG members help you. Post your issues!
COBOL Job Resources COBOL Jobs Here are references to a wealth of job resources, including job listing sites, resume preparation, and interview questions.
Job and Resume Matchmaker! COBOL Jobs Employers submit your COBOL job openings. Job seekers submit your resumes.
COBOL (c) Information Computing Services. All Rights Reserved. COBOL
¤ Dauer der Verarbeitung: 0.15 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.