Calculator

F

Flipke

Hello,

I wanna make a calculator where i can give the input in one word. for
example : (15*3) / (2+3)
I think i most read this in as a string and then share it in different parts
to do the calculation. But i don't now how tho start with it. Can somebody
help me.

Thanks in advanced.
 
D

David Resnick

Flipke said:
Hello,

I wanna make a calculator where i can give the input in one word. for
example : (15*3) / (2+3)
I think i most read this in as a string and then share it in different parts
to do the calculation. But i don't now how tho start with it. Can somebody
help me.

Thanks in advanced.

You might ask your teaching assistant/professor for some hints on how
to get started on your homework.

You could also google for "recursive descent parser", that being a
standard approach for this sort of problem. K&R also has an
calculator, though
their example program uses RPN.

-David
 
M

Mike Wahler

Flipke said:
Hello,

I wanna make a calculator where i can give the input in one word. for
example : (15*3) / (2+3)
I think i most read this in as a string and then share it in different
parts
to do the calculation.

Yes, 'divide and conquer' is a good practice in programming.
But i don't now how tho start with it.

First, as you said, read the input. The next step
is to parse it into meaningful segments (e.g. (15 * 3),
15, etc.). You'll need to keep track of the parentheses
in order to implement the correct precedence of the
arithmetic operations. A recursive approach is the most
common approach to this kind of problem.

Can somebody
help me.

Yes, but we need something to help you with. Nobody will
write it for you. Show the code of your best attempt, and
ask specific questions.

-Mike
 
J

Julian V. Noble

Flipke said:
Hello,

I wanna make a calculator where i can give the input in one word. for
example : (15*3) / (2+3)
I think i most read this in as a string and then share it in different parts
to do the calculation. But i don't now how tho start with it. Can somebody
help me.

Thanks in advanced.

Have a look at Kruse, "Data Structures and Program Design". He shows how
to develop a simple formula evaluator. IIRC he uses a parse tree rather
than recursive descent. His original version used Pascal, but that's close
enough to C to translate. Or you might look at a more recent edition--
I think he has ceased fighting the inevitable and now uses C or C++ as his
illustration language.


--
Julian V. Noble
Professor Emeritus of Physics
(e-mail address removed)
^^^^^^^^^^^^^^^^^^
http://galileo.phys.virginia.edu/~jvn/

"For there was never yet philosopher that could endure the
toothache patiently."

-- Wm. Shakespeare, Much Ado about Nothing. Act v. Sc. 1.
 
N

Neil Kurzman

Flipke said:
Hello,

I wanna make a calculator where i can give the input in one word. for
example : (15*3) / (2+3)
I think i most read this in as a string and then share it in different parts
to do the calculation. But i don't now how tho start with it. Can somebody
help me.

Thanks in advanced.

As I recall in data structures you can use stacks to convert it to RPN, then
push that on to 2 stacks to calculate it.
BTW the question is off topic.
 
O

osmium

Julian V. Noble said:
Have a look at Kruse, "Data Structures and Program Design". He shows how
to develop a simple formula evaluator. IIRC he uses a parse tree rather
than recursive descent. His original version used Pascal, but that's close
enough to C to translate. Or you might look at a more recent edition--
I think he has ceased fighting the inevitable and now uses C or C++ as his
illustration language.

Just out of curiosity I looked up the C/C++ version of the Kruse book on
Amazon to read the reviews. I have never seen such a collection of hateful
reviews of a book! I don't think it is possible to "salt" Amazon without a
great deal of effort so the book is likely despised by these people (31),
mostly students. As I understand it, he uses STL to explain data structures
which seems like a bad approach to me. A data structures class should be
*writing* STL , not *using* it. In any event I simply must see a copy of
this book. AFAIK there is no ACCU review.

Back to the OPs question. My guess is that most of the answers are too
high falutin' for what he is expected to do. If this is a first semester
class, surely the instructor doesn't expect him to get into recursive
descent parsers and all that stuff. I would expect a student in a later
course to phrase the question differently. And there is also the slim
possibility that it isn't a student problem at all.
 
I

italy

Flipke said:
Hello,

I wanna make a calculator where i can give the input in one word. for
example : (15*3) / (2+3)

It's an expression, not a word. (note an expression is a collection of
operands and operators, or in some cases only operand(s))
I think i most read this in as a string and then share it in different parts
to do the calculation. But i don't now how tho start with it. Can somebody
help me.
Break the problem down. I recommend writing a simple RPN calculator
first, because it's the easiest.
 
W

Walter Roberson

Just out of curiosity I looked up the C/C++ version of the Kruse book on
Amazon to read the reviews. I have never seen such a collection of hateful
reviews of a book! I don't think it is possible to "salt" Amazon without a
great deal of effort so the book is likely despised by these people (31),
mostly students.

There was a scandal not long ago in which it turned out that
a bunch of Amazon "reviewers" were the authors themselves -- and
sometimes more than one "review" of their own books. "Salting" Amazon
is, then, perhaps a bit easier than you might expected.
[NB, I know nothing about the merits of the book in question.]
 
M

Malcolm

Flipke said:
I wanna make a calculator where i can give the input in one word. for
example : (15*3) / (2+3)
I think i most read this in as a string and then share it in different
parts
to do the calculation. But i don't now how tho start with it. Can somebody
help me.
To write a parser, firstly many of the rules of good programming don't apply
to parsers.
Normally the caller should ensure that the input is valid. For a parser, the
caller cannot do this without without writing another parser himself. So you
have to be very careful about handling errors.
Normally you should not have mutually recursive functions. For a parser,
this structure is natural.
Normally you should not have global variables. A parser is one place where
code is often neater if you do use globals.

How do you do it? The basic principle is that when you hit a bracket, you
call the top-level function on the contents. This is why parsers are
mutually recursive.

Arithmetical expressions have the bodmas (brackets, of, divide, multiply,
add, subtract) rule.

What you want to do is declare a global pointer to input so far. Then you
write a function called gettoken() which returns the token (number,
operator, parentheses) in the input stream, but does not remove it. Then
write a function called match() which discards the token from the stream,
but only if it is of the type passed. Otherwise it flags an error.

Then write three functions, expression(), term() and factor(). A factor is
either a raw number or an open parenthesis containing an expression
(recursion). A term is either a raw factor, or a series of factos connected
by divides and multiplies. An expression is either a raw term, or a series
of terms connected by additions and subtractions.

Once you have all this working, you basically have your calculator. It is
quite hard, so post your attempt if you get stuck.
 
W

Walter Roberson

To write a parser, firstly many of the rules of good programming don't apply
to parsers.
Normally the caller should ensure that the input is valid.

[Good] programs are full of "validate" functions which don't know if
their input is valid until they look at it.

A database "find and lock" (to avoid race conditions) routine won't
know whether the input field is a match until it does the search.

It's normal defensive programming to assume that the input might not
be valid and to protect against such cases. Think of all the verbage
about how strcpy() is a fault in the design of C and it becomes clear
that it's often a bad idea to -assume- that all necessary checks
have been done before a routine is called.
Normally you should not have mutually recursive functions.

Sez who? ;-)

The difficulty with mutually recursive functions is in the possibility
of indefinite stack space usage. The alternative to recursive functions
is to write the equivilent iterative function -- but the equivilent
iterative function will often need indefinite memory allocation
and so suffer the same fate [except that you can detect failed
memory allocation but you can't detect whether there's enough room
to call any particular function.]
Normally you should not have global variables.

Ah? This is comp.lang.c . The operation of fopen() and kin use
global variables almost by definition, and there's no other I/O
operators available, so compliant hosted programs will almost always
use global variables.
 
J

Jonathan Adams

Ah? This is comp.lang.c . The operation of fopen() and kin use
global variables almost by definition, and there's no other I/O
operators available, so compliant hosted programs will almost always
use global variables.

How's that? I can store a FILE * in any number of ways, none of which
require global variables.

If you're saying that stdin, stdout, and stderr are globals, what does
it matter?

Cheers,
- jonathan
 
K

Keith Thompson

Jonathan Adams said:
How's that? I can store a FILE * in any number of ways, none of which
require global variables.

Sure but the FILE object it points to is almost certainly global.
If you're saying that stdin, stdout, and stderr are globals, what does
it matter?

I'm not sure what you're asking.
 
P

Purnank

Mike Wahler said:
Yes, 'divide and conquer' is a good practice in programming.

No, Divide and conquer is not the solution,
the solution is tranform / convert.

(15*3) / (2+3) --> this is not the thing you need. you may divide it upto a
small level but after some stage, things would not be as easy.
Convert the problem into Reverse Polish Notation.

(15*3) / (2 + 3)
===
You differntite operations and operands,

e.g.
2+3 is written as + 2 3
3*2 + 1
should be written as
+ * 3 2 1
Add the product of 3 and 2 to one.

+ _*_3_2_ 1
+ 6 1
7

To start with, do not use 15 , 16 ( 2 digit numbers, use 1 digit number, and
+ * - as simple operators. )

Then convert into POLISH notations.

"you need to go to *algorithms* not *lang.c*"

First, as you said, read the input. The next step
is to parse it into meaningful segments (e.g. (15 * 3),
15, etc.). You'll need to keep track of the parentheses
in order to implement the correct precedence of the
arithmetic operations. A recursive approach is the most
common approach to this kind of problem.



Yes, but we need something to help you with. Nobody will
write it for you. Show the code of your best attempt, and
ask specific questions.

-Mike
Purnank.
 
J

Julian V. Noble

osmium said:
Just out of curiosity I looked up the C/C++ version of the Kruse book on
Amazon to read the reviews. I have never seen such a collection of hateful
reviews of a book! I don't think it is possible to "salt" Amazon without a
great deal of effort so the book is likely despised by these people (31),
mostly students. As I understand it, he uses STL to explain data structures
which seems like a bad approach to me. A data structures class should be
*writing* STL , not *using* it. In any event I simply must see a copy of
this book. AFAIK there is no ACCU review.

Well, I rather liked the book and found it helpful when I first encountered
the Pascal version back in the late 1980's. I see some of the reviewers really
trashed it. Possibly the 2nd edition of the C version (revised by colaborators)
isn't as good as the original. That would come as no surprise---I can name half
a dozen texts that were first rate in their original edition and that got pro-
gressively worse with each succeeding one.

--
Julian V. Noble
Professor Emeritus of Physics
(e-mail address removed)
^^^^^^^^^^^^^^^^^^
http://galileo.phys.virginia.edu/~jvn/

"For there was never yet philosopher that could endure the
toothache patiently."

-- Wm. Shakespeare, Much Ado about Nothing. Act v. Sc. 1.
 
J

Jonathan Adams

Keith Thompson said:
Sure but the FILE object it points to is almost certainly global.

Which, if true,[1] would be an implementation detail of libc that
doesn't impact its users. The interface is all in terms of FILE
pointers.

The basic advice "Normally you should not have global variables" is
reasonably sound, if a little too black-and-white. At the very least,
global variables should be used with care.

Cheers,
- jonathan

[1] I've seen versions of libc which dynamically allocates their FILE
*s, beyond a certain point. For example, the Solaris implementation.
I'm fairly certain any reasonably modern UNIX will do so. stdin,
stdout, and stderr all have to be statically allocated, of course.
 
W

Walter Roberson

stdin,
stdout, and stderr all have to be statically allocated, of course.

C89 indicates that they are "expressions" of type FILE*, so
in -theory- they could perhaps be functions that return the appropriate
address, such as an address of a static variable with file scope
instead of a global variable. I don't remember reading anything
that would -require- that globals be used for those three. On the
other hand, I don't think I have ever run into an implementation where
they weren't globals. (Hence my qualification "almost by definition".)
 
M

Malcolm

Jonathan Adams said:
Which, if true,[1] would be an implementation detail of libc that
doesn't impact its users. The interface is all in terms of FILE
pointers.

The basic advice "Normally you should not have global variables" is
reasonably sound, if a little too black-and-white. At the very least,
global variables should be used with care.
One of the weaknesses of C is that there is no distinction between a
"function", which calculates something, and a "procedure" which does
something, i.e. interacts with hardware.
Procedures naturally contain global variables, because the computer is
attached to various shared devices. Functions don't (though malloc() is a
special case), because a function is naturally defined by its parameters.
Good design normally involves separating your functions from your
procedures.
 
K

Keith Thompson

Malcolm said:
One of the weaknesses of C is that there is no distinction between a
"function", which calculates something, and a "procedure" which does
something, i.e. interacts with hardware.
Procedures naturally contain global variables, because the computer is n
attached to various shared devices. Functions don't (though malloc() is a
special case), because a function is naturally defined by its parameters.
Good design normally involves separating your functions from your
procedures.

What some languages (e.g., Pascal) call a "procedure" is simply a
function returning void in C. There's no implication that a procedure
interacts with hardware and/or refers to global variables, nor is
there any particular implication (apart from style, perhaps) that a
function doesn't. A procedure can interact only through its
parameters just as easily as a function can interact only through its
parameters and result. The only difference is that a procedure
doesn't return a value.

A trivial example:

void increment(int *n)
{
*n ++;
}

Perhaps you're using the term "procedure" to refer to some other
concept.
 
M

Mark McIntyre

Convert the problem into Reverse Polish Notation.

What on earth for? Simply write a parser (or better yet, download one
already-written and tested) , and move on.
"you need to go to *algorithms* not *lang.c*"

this is correct.
 
R

Richard Bos

Malcolm said:
Jonathan Adams said:
Which, if true,[1] would be an implementation detail of libc that
doesn't impact its users. The interface is all in terms of FILE
pointers.

The basic advice "Normally you should not have global variables" is
reasonably sound, if a little too black-and-white. At the very least,
global variables should be used with care.

One of the weaknesses of C is that there is no distinction between a
"function", which calculates something, and a "procedure" which does
something, i.e. interacts with hardware.

You forget a "functure", which interacts with the hardware and then
calculates something from the result; a "fucedure", which calculates
something and then sends the result to hardware; and a "procion", which
neither interacts with hardware, nor calculates something.

Gosh. Am I dismayed at the lack of such a proliferation of routine types
in C! We must've been living in the dark ages of computing for years,
when we could have had all these separate "functions" and "procedures",
all with their own declaration types, to enliven our code! Makes me want
to bail out of C and start using ADA, that, it really does.

Richard
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,571
Members
45,045
Latest member
DRCM

Latest Threads

Top