$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 occurs128indexed 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 move1to sp move zeros to stack-number (1) move'+'to stack-operation (1) set x-in to1 perform one-word until x-in greaterthan128 if sp notequalto1 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 upby1
. 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) add1to p end-if end-if set x-in upby1 end-perform set x-in downby1
. 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 lessthan10 add1to sp else display'stack overflow' end-if
. dec-sp. if sp greaterthan1 subtract1from sp else display'too many right parens' end-if
. display-c. if a-digit in c (1) equalto9 call'CALCNEG'using a, b, c display'-'withnoadvancing end-if performvarying i from1by1until
a-digit in c (i) not = zeroor i > 99 continue end-perform performvarying i from i by1until 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 if9not = a-digit in b (1) and a-digit in a (1) move0to overflow-digit perform add-operation else if9 = a-digit in b (1) and a-digit in a (1) move1to overflow-digit perform add-operation else perform flip-sign-b perform compute-a-minus-b end-if
. add-operation. performvarying i fromlengthof huge by -1until i lessthan1 compute temp-s =
a-digit in a (i) + a-digit in b (i) + overflow-digit if temp-s lessthan10 move temp-s to a-digit in c (i) move0to overflow-digit else subtract10from temp-s giving a-digit in c (i) move1to overflow-digit end-if end-perform
. compute-a-minus-b. movezeroto overflow-digit if b greaterthan a move1to overflow-digit end-if performvarying i fromlengthof huge by -1until i lessthan1 compute temp-s =
a-digit in a (i) - a-digit in b (i) - overflow-digit if temp-s lessthanzero add10to temp-s giving a-digit in c (i) move1to overflow-digit else move temp-s to a-digit in c (i) move0to overflow-digit end-if end-perform
. compute-a-times-b. perform normalize-sign-in move zeros to d performvarying i fromlengthof huge by -1until i lessthan1 if a-digit in b (i) notequaltozero compute k = i + (lengthof huge / 2) performvarying j fromlengthof huge by -1until j lessthan1 if a-digit in a (j) notequaltozeroand
k notless1andnotgreaterlengthof huge compute two-digits =
a-digit in a (j) * a-digit in b (i) perform add-two-digits end-if subtract1from 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 subtract1from k end-perform move zeros to d performuntil k > lengthof huge performuntil b greaterthan a or b = zeros move1to two-digits perform add-two-digits perform compute-a-minus-b move c to a end-perform perform shift-b-right add1to 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) equalto9or 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 move1to 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 from1by2until delta = zeroor t > 90
* compute ln = ln + ((2 / t) * (((x - 1) / (x + 1)) ^ t))
* where0 < x < e move temp-a to a movezeroto b move1to 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 from1by2until
b(1:(lengthof huge / 2) + 16) = zeroor term > 90or
b(1:(lengthof huge / 2) + 16) = all'9' movezeroto a, b move2to 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 from1by1until delta = zeroor t > 90
* compute exp = exp + ((x ^ t) / t!)
* add1to 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 move1to a-digit in b (lengthof huge / 2) move b to temp-3 performvarying term from1by1until
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 move5to 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 move1to 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 move1to a-digit in a (lengthof huge / 2),
a-digit in b (lengthof huge / 2) performvarying factorial from1by1until 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 move0to digit-1 subtract1from l end-perform
. normalize-sign-in. movezeroto sign-count if a-digit in a (1) equalto9 add1to sign-count perform flip-sign-a end-if if a-digit in b (1) equalto9 add1to sign-count perform flip-sign-b end-if
. normalize-sign-out. if sign-count equalto1 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
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-06-11)
¤
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 und die Messung sind noch experimentell.