-
Notifications
You must be signed in to change notification settings - Fork 33
/
14.44.cpp
65 lines (58 loc) · 1.48 KB
/
14.44.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/*
* Exercise 14.44: Write your own version of a simple desk calculator that can
* handle binary operations.
*
* By Faisal Saadatmand
*/
#include <exception>
#include <functional>
#include <iostream>
#include <map>
#include <cmath>
#include <sstream>
double add(const double i, const double j)
{
return i + j;
}
class divide {
public:
double operator()(const double denominator, const double divisor);
};
double
divide::operator()(const double denominator, const double divisor)
{
if (!divisor)
throw std::invalid_argument("zero divisor");
return denominator / divisor;
}
auto mod = [](const int i, const int j)
{ return (!j) ? throw std::invalid_argument("zero divisor") : i % j; };
int main()
{
std::map<std::string, std::function<double(double, double)>> binops = {
{"+", add},
{"-", std::minus<double>()},
{"/", divide()},
{"*", [](const double i, const double j) { return i * j; }},
{"%", mod},
{"^", [](const double i, const double j) { return pow(i, j); }}
};
while (true) {
std::string op, input;
double lhs, rhs;
if (!std::getline(std::cin, input) || input == "q")
break;
try {
std::istringstream line(input);
if (!(line >> lhs >> op >> rhs))
throw std::invalid_argument("invalid expression");
auto key = binops.find(op);
if (key == binops.cend())
throw std::invalid_argument("invalid operator");
std::cout << key->second(lhs, rhs) << '\n';
} catch (std::invalid_argument err) {
std::cerr << err.what() << '\n';
}
}
return 0;
}