-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.cpp
180 lines (147 loc) · 5.12 KB
/
main.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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# include <iostream>
static const int NEG_SIGN_ASCII = 0x2D;
static const int ZERO_ASCII = 0x30;
static const int NINE_ASCII = 0x39;
static const int MAX_INT_DECIMAL_LEN = 6;
static const int MAX_INT_BINARY_LEN = 0xF;
// Converts a stream of characters to a string.
void inputToString(std::string& inputSaveString){
char charInput;
inputSaveString = "";
while(1){
std::cin >> std::noskipws >> charInput;
if(charInput == '\n')
break;
inputSaveString += charInput;
}
}
// Checks if the string has any non-numeric values
// or if the string is empty.
void verifyInput(std::string& inputString){
bool validInput = 0;
// Check if you have a non-numerical value in your string
while(!validInput) {
validInput = 1; // If loop finishes without error, then we should be fine.
for (std::string::size_type i = 0; i < inputString.size(); i++) {
char c = inputString.at(i);
// Compare character to ASCII table:
// Accepts only if numeric value or if it's a '-' at the first input
if ((c > NINE_ASCII) | (c < ZERO_ASCII && !(i == 0 && c == NEG_SIGN_ASCII))) {
std::cout << "You have entered a non-numeric value. Please try again. \n";
inputToString(inputString);
validInput = 0;
break;
}
}
// If provided with empty string
if (inputString.size() == 0) {
std::cout << "You must supply a number. Please try again. \n";
inputToString(inputString);
validInput = 0; // Need to check again if the user has input non-numeric values
}
}
}
int timesTen(const int value){
return (value << 3) + (value << 1);
}
// Converts string to int
int stringToInt(std::string& inputString){
signed short int result = 0;
char c = inputString.at(0);
typedef std::string::size_type sz;
// Negative
if(c == 45){
for(sz i=1; i < inputString.size(); i++){
int intAtPosition = inputString.at(i) - ZERO_ASCII;
result = timesTen(result) + intAtPosition;
}
result = ~result+1; // Two's complement
}
else{
for(sz i = 0; i < inputString.size(); i++) {
int intAtPosition = inputString.at(i) - ZERO_ASCII;
result = timesTen(result) + intAtPosition;
}
}
return result;
}
// Converts int to string by
// naive implementation of division by repeatedly subtracting powers of ten.
// For negative numbers, run the fxn as a positive and add the signbit later.
std::string intToString(int m){
signed short int firstBit = 0x8000; // 1000 0000 0000 0000
bool isNegative = false;
// Checks if the input is negative; if so, make it positive & save negativity
// Checking for negativity is done with AND with 1000 0000 0000 0000.
if(m & firstBit){
m = ~m + 1;
isNegative = true;
}
// Initialize array of powers of ten
// Results in: powersOfTen = {10^5, 10^4, 10^3, 10^2, 10, 1}
int powersOfTen[MAX_INT_DECIMAL_LEN];
powersOfTen[MAX_INT_DECIMAL_LEN-1] = 1;
for(int i=MAX_INT_DECIMAL_LEN-2; i>=0; i--) {
int p = powersOfTen[i+1];
int pp = timesTen(p);
powersOfTen[i] = timesTen(powersOfTen[i + 1]);
}
// Repeatedly subtract powers of ten
std::string resultString;
for(int i=0; i < MAX_INT_DECIMAL_LEN; i++){
char tempChar = ZERO_ASCII;
int powerOfTenVal = powersOfTen[i];
while(m - powerOfTenVal >=0){
m -= powerOfTenVal;
tempChar += 1;
}
resultString += tempChar;
}
// Add sign if negative
if(isNegative){
resultString = char(NEG_SIGN_ASCII) + resultString;
}
return resultString;
}
int multiply(int mCand, int mPier){
signed short int product = 0;
signed short int firstBit = 0x8000; // 1000 0000 0000 0000
bool isNegative = false;
// Checks if the input is negative; if so, make it positive & save negativity
// Checking for negativity is done with AND with 1000 0000 0000 0000.
if(mCand & firstBit){
mCand = ~mCand + 1;
isNegative = !isNegative;
}
if(mPier & firstBit){
mPier = ~mPier + 1;
isNegative = !isNegative;
}
// Shifting-based multiplication algorithm
for(int i=0; i < MAX_INT_BINARY_LEN; i++){
if(mPier & 1){
product += mCand;
}
mCand = mCand << 1;
mPier = mPier >> 1;
}
if(isNegative){
product = ~product + 1;
}
return product;
}
int main(){
while(true){
std::string input1 = "", input2 = "";
std::cout << "Enter the multiplicand: ";
inputToString(input1);
verifyInput(input1);
std::cout << "Enter the mulitplier: ";
inputToString(input2);
verifyInput(input2);
int mCand = stringToInt(input1), mPier = stringToInt(input2);
int multProduct = multiply(mCand, mPier);
std::cout << "The product is: " << intToString(multProduct) << "\n\n";
std::cout << "Congratulations, you have won! \nNew multiplication loading... \n\n";
}
}