Does anybody know what this code does?

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.

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
#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 >_>
Last edited on
closed account (3hM2Nwbp)
If I had to guess:

a compile-time error at line 3 because that code can't exist at global scope.

a compile-time error for an undeclared identifier 'cin' at line 4

a compile-time error for an undeclared identifier 'cout' at line 14

a compile-time error for an undeclared identifier 'endl' at line 14

<after fixing compile-time errors>

a run-time anomaly when the user enters a non-digit at line 4

:)

<assuming valid input>

After running 3 simple value sets in my head, it appears that it's multiplying n by m.
Last edited on
Man, you are so exigent >_>
It's just a simple example.
Last edited on
closed account (3hM2Nwbp)
Programmers eventually go bonkers. I'm in an early stage of the madness.
@oldcrow
i tried it out...it will find multiplication of n and m;
x = n * m;
What book r u reading?
i think abs(m*n) naa, maybe i'm wrong anyway good example. I recall my highschool days.
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
@Script Coder

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.
Last edited on
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.
OR if you want to know what exactly the * operator does.


The * operator does not do what your code is doing.
@Disch

Then what does it does??
Last edited on
closed account (3hM2Nwbp)
::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.

Oo...here's a good article.

http://en.wikipedia.org/wiki/Binary_multiplier
Last edited on
oldcrow:

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.
Last edited on
I wonder what would've happened if they taugh us to multiply like this in elementary school? 0_o
Weird... that was what they taught me.
But they used another base ;)
Looks to me like standard long multiplication in base 2!

Thanks for the interesting code, I had to write out an example before I realised it was long multiplication.

In return I'll give you the same code but what I believe makes better use of C++:

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
#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.
@Veltas:
Thanks for your code! I'm still new to C++ and I'm not used to its features yet, so your code will be helpful.
In that case, allow me to elaborate.

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).
Last edited on
Again, thanks for the explanation!
Topic archived. No new replies allowed.