Hello everybody! I was reading some programming books at school and I found an interesting piece of code that I want to share with you. Try to discover what it does WITHOUT COMPILING.
#include <iostream>
#include <string>
int main (int argc, char *argv[])
{
int n, m, x = 0;
std::string a, b;
do {
std::cout << "Enter a number: ";
getline(std::cin, a);
std::cout << "Enter another number: ";
getline(std::cin, b);
try {
n = std::stoi(a);
}
catch(...) {
std::cout << "Error: 1st input is not a number!" << std::endl;
n = -1;
}
try {
m = std::stoi(b);
}
catch(...) {
std::cout << "Error: 2nd output is not a number!" << std::endl;
m = -1;
}
} while ((n < 0) || (m < 0));
while (m != 0) {
if (m % 2 != 0)
x = x + n;
n = n + n;
m = m / 2;
}
std::cout << "The result is: " << x << std::endl;
std::cout << std::endl << "Press any key to quit...";
std::cin.get();
return 0;
}
Hope you enjoy it! =D
EDIT: Thanks to Luc Lieber, I wrote the "complete" code >_>
First it declares 5 variable, 3 integers(n, m and x(x is initialazed to 0)) and 2 std::strings(a and b) then it prompts the user to enter 2 numbers, and it inputs them in the strings a and b, respectivy. then it uses the std::stoi function to transform the numbers into integers, and stores them into n and m, respectivelly. Then it runs that number-entering code untill both n and m are negative. After that it enters a while loop(that goes untill m is 0) that first checks if m is evenly divizible by 2(if not, increases x by n) and then increases n by n, and divdes m by 2. Then it outputs the number x as the "result" and waits for the user to press a key, and then exits.
I did it all without looking at other posts, or compiling
The book is called "Creative and Recreative Programming Excercises in C++" in English, from Prentice Hall Editorial. I don't know if there is an English version though. It is quite interesting... and hard sometimes.
Well, everybody got it right, this is a multiplication algorithm. I wonder what would've happened if they taugh us to multiply like this in elementary school? 0_o
If anybody is still interested in this post, this algorithm has been known since ancient times in Eastern Europe and it is a variant from the egiptian multiplication algorithm. Guess this is only important when you are trying to 'teach' a computer how to multiply, OR if you want to know what exactly the * operator does.
::operator* may either use an assembly operation to either bitshift or multiply, depending on the operands. How the hardware does the bitshift / multiply logic is implementation defined. Hey, compilers might even have other sneaky tricks that I don't know about...you never know.
multiplication and addition have been separate instructions in mainstream processors for decades. The * operator likely compiles to the 'mult' instruction, whereas the loop you posted will likely compile to a series of 'add' instructions.
Since * and + will compile to vastly different code... saying "if you want to know exactly what the * operator does" is very misleading, because the * operator does exactly something else entirely.
@Luc Lieber & Disch
Huh, funny. I thought the explanation would be something much more complicated than that. Thanks to point out my mistake by the way, and to correct me kindly.
#include <iostream>
int main ()
{
int n, m;
std::cout << "Enter a number: ";
std::cin >> n;
std::cin.sync();
std::cout << "Enter another number: ";
std::cin >> m;
std::cin.sync();
int x = 0;
while (m) {
if (m % 2) x += n;
n *= 2;
m /= 2;
}
std::cout << "The result is: " << x << std::endl;
return 0;
}
Also, this 'binary multiplication' used to be a trick people used to multiply numbers back before nice number systems like decimal, and tools like long multiplication that I described before. After all, you only need to be able to add, double and half; simple operations for any arithmetic novices.
The I/O Streams should be used for formatting, because they use different versions of methods in order to evaluate expressions. For example, giving an int to std::cin will format the input as an integer. This is a concept called operator overloading, if it doesn't make sense now come back to this later when you've learned about this. It is a powerful feature because one can use similar code to perform wildly different operations according to the type of data given.
Also you'd written things like x = x + n; which can be replaced with x += n;, which is a feature called compound assignment. This is a shorter way of writing these sorts of assignment statements, and in some situations can increase the efficiency of the code (although usually the compiler is clever enough to detect such opportunities for improvement).
At one point you write n = n + n;, which could be written as n += n; with compound assignment, but better yet it is mathematically equivalent to n *= 2; so really you should've written that instead!
EDIT: I should also probably elaborate on the function of std::cin.sync(). This method drops any extra numbers that may have been inputted and makes sure the console is ready to accept a new number, as you could input multiple numbers at once; the std::cin >> n; expression only extracts the first number! If you don't have the sync method then if multiple numbers were added before and you extract an integer again, then it will take the second number inputted, and won't pause at all. So the sync statement is to avoid what would seem strange behaviour in the Command Prompt (or terminal or whatever).