To read all comments associated with this story, please click here.

I don't really use C++ but that seems a bit low-level - why assume 32-bit signed with a two's complement representation - or rounding errors from roots - when you could just multiply by -1 if <0 which would also work with doubles or (unexpected) unsigned and wouldn't tie you to a particular (albeit standard) low-level representation? Then when the program evolves some time later, with different developers, they don't have to chase obscure assumptions. I guess that doesn't apply here though else the code would just be an abs function :-)

I do know that the point you're making is totally true. I think it's because you can't learn programming by applying it to toy problems, no matter how much computer science you know. You have to go through the bitter experience of getting real projects to work.

The point of these types of questions is to see whether an applicant can think of an efficient solution to a problem using a language he/she is most familiar with. I could've asked him to write a code for something more serious, but really if one couldn't come up with a simple solution to a simple problem, I doubt he/she could tackle more complicated problems. I've seen this pattern repeatedly.

"

*int myAbs(const int num) { return num < 0 ? (~num) + 1 : num; }*

*"*

There is another way: multiply the number by itself and return the square root of the multiplication (which will make it work with real numbers if you replace all instances of 'int' with 'double'). But the above code should suffice, given the requirement explicitly states 'some 32-bit signed integer'.

Computer Engineering/Computer Science graduates who don't understand why or how the above code works have wasted years of life studying a subject they're not even interested in.

There is another way: multiply the number by itself and return the square root of the multiplication (which will make it work with real numbers if you replace all instances of 'int' with 'double'). But the above code should suffice, given the requirement explicitly states 'some 32-bit signed integer'.

Computer Engineering/Computer Science graduates who don't understand why or how the above code works have wasted years of life studying a subject they're not even interested in.

Thank you for reminding me to re-teach myself two's complement. Last time I learned it, I was sleepy, rushed, and hadn't discovered Taskwarrior.

(Because I don't remember the relationship between one's complement and two's complement enough to use it from memory, I'd have multiplied by -1 to convert instead... or just used abs() in a practical situation. 95% of the code I've had to write has been in Python lately and the rest in bash script.)

Yes, sure... There's abs(). There are a gazillion other functions offered by various 3rd-party libraries for various purposes. Heck, one could even Google for solutions to basic programming problems. But a) we cannot always depend on 3rd-party solutions in real projects (most of the times we have to implement our own libraries or at least fork something that's closest to our requirements), and b) we need a programmer who can come up with good solutions without depending on Google Search.

If one doesn't remember such a basic thing he/she learned at school, what else has he/she forgotten?

"int myAbs(const int num) { return num < 0 ? (~num) + 1 : num; }"

There is another way: multiply the number by itself and return the square root of the multiplication (which will make it work with real numbers if you replace all instances of 'int' with 'double'). But the above code should suffice, given the requirement explicitly states 'some 32-bit signed integer'.

Computer Engineering/Computer Science graduates who don't understand why or how the above code works have wasted years of life studying a subject they're not even interested in.

Just out of curiosity, would this have been a valid option in your opinion ?

int absolute(const int num) { return (num>=0)?num:-num; }

That would pretty much have been my spontaneous answer to your problem (except with an if ... else structure instead of the trigraph).

Addendum:

And btw, both your solution and the solution I wrote in my original post have a bug, which I would've asked about, if he would've come up with something similar to mine or yours. But this follow-up question is only meant to test his mastery, which is not compulsory for the position he was being interviewed for. We don't want to assign maintenance works to someone who really masters his/her field -- such person deserves more challenging tasks.

In case anyone is curious, this one liner function gives you the absolute value of some 32-bit integer 'num':

"

*int myAbs(const int num) { return num < 0 ? (~num) + 1 : num; }*

*"*

There is another way: multiply the number by itself and return the square root of the multiplication (which will make it work with real numbers if you replace all instances of 'int' with 'double'). But the above code should suffice, given the requirement explicitly states 'some 32-bit signed integer'.

There is another way: multiply the number by itself and return the square root of the multiplication (which will make it work with real numbers if you replace all instances of 'int' with 'double'). But the above code should suffice, given the requirement explicitly states 'some 32-bit signed integer'.

I actually have few issues with your code.

1. Why do you use trigraph here? It only makes code it harder to read. Not by much, but still, I need to stop for few seconds to decipher that line.

*If ... else*block would be much nicer.

2. I try to use trigraphs only in combination with boolean values:

*return isPositive ? num : (-1)*num;*

This form makes it much easier to read the code. Boolean expressions fit much nicely in

*if ... else*block.

These two points might be a personal preference, but I believe that code readability is the most important thing in coding (I did work in design maintenance for years, so my views are a bit distorted though)

3. Why not use

*abs*function? Why do you need an implementation of your own? My response during the interview would be: There is already a function that does just that, in C/C++ I would use

*abs*. One downside is the ugliness of using

*abs labs, cabs, llabs, fabs*for different number types, but your example was about

*int*s, so

*abs*would be a natural choice.

4. And finally, the implementation itself.

Why would you use two's complement for such trivial thing? Two's complement is something they teach you at the university, and 99% of people forget about it before they graduate. That means more likely that not, other programmers will not be able to figure out your code at first glance.

What would be the reason for this kind of complexity? Speed of execution? Why don't we let compiler worry about that, and just write

*num*(-1)*?

I work in a company where programmers regularly write functions that wrap assembler code. You see, our in house compiler is not very smart with optimizations, but for regular C/C++ I'd recommend letting compiler optimize such trivial things like

*num*(-1)*.

5. What to say about your other solution?

That one is almost in the league of what student wrote. Multiply, than square root? Compared to

*num*(-1)*logic is complex and there's just too much work.

Other than this example, I support your comment 100%.

BR

Loreia

Nitpick: "Trigraphs" -> http://de.wikipedia.org/wiki/Trigraph

You really meant "Ternary Operator", often called "The Ternary [Operator]", because there is only one in both C and C++.

Then: Instead of multiply by -1, just use the unary negation operator.

I disagree about the bad readability of the ternary operator. It is just as readable as an if-statement or class-declarations. The one thing you have to do, like with all other things in C++, you just learn it. That's it.

As with if-statements, while-loops and everything else, you only have to know when to use, and not exaggerate it (again, like with other things in C++).

Apart from that, I totally agree to your last three points.

*Edited 2012-09-25 08:59 UTC*

Question no. 1:

Really? we encounter ternary operator on a day-to-day basis. It's very common here. That snippet in my original post is just an example, for the sake of brevity.

Question No. 3:

This is already answered in one of my earlier replies. To put it another way, my question to the applicant was essentially "could you write an example of abs() implementation for me?".

As for No. 4:

Very few people forget such basic operation. Most fresh (or semi-fresh) grads still remember. And it's not a matter of optimization whatsoever. Again, that's just an example. It doesn't mean I would frown at solutions different from mine. I just don't like bad solutions.

Even the solution I wrote in my original post has a bug, which I would've asked about, if he would've come up with something similar. But this follow-up question is only meant to test his mastery, which is not compulsory for the position he was being interviewed for.

Question No. 5:

Given such solution, I would ask the applicant about overflows, but again, this is a test of mastery and is not compulsory for the position in question, but a test that must be performed nonetheless.

Why so complicated:

int abs (int val) {

return val<0 ? -val : val;

}

or

template <typename T>

T abs (T const &val) {

return val<0 ? -val : val;

}

and squaring the number first is, in the real world, prone to overflow and assumes the presence of a square rooter.

But I am glad you and your friendly colleague enjoyed your sadism over that poor soul.

Yes, you would get a big smile from me for writing such code. But still, it contains the same bug as my example and I'd ask you about that.

Sadism? No at all. By that I mean we weren't making fun of the individual, we were just laughing at the funny code he wrote. We never even care whether an applicant is normal looking or not, or whether he walks on his two feet or rolls in a wheelchair.

"

*int myAbs(const int num) { return num < 0 ? (~num) + 1 : num; }*

*"*

**Big fail!**, what about INT_MIN?

The absolute value of a 32-bit integer needs to be given on a >32bit integer type.

JeeperMate,

"int myAbs(const int num) { return num < 0 ? (~num) + 1 : num; }"

I concur with everyone else that taking the not and adding one is a roundabout way of calculating what we really want, which is a simple negation.

However I'll go one further and claim that your solution is potentially invalid because you make an assumption about two's compliment that C doesn't guarantee. In fact it explicitly lists 3 different number sign representations.

http://stackoverflow.com/questions/3952123/representation-of-negati...

Now I'm clearly playing devil's advocate here, but arguably an ABS function implementation that converts an integer to string and removes the sign character is, according to the C standard, more correct than one that makes assumptions about the bits.

All this time you were laughing at him, and yet his inefficient solution may have been more correct than yours. I hope you can laugh at the irony.

Member since:

2010-06-12

From my experience interviewing hundreds of Computer Engineering/Computer Science graduates all these years, I can say most of them fulfill the following condition:

if ( !(developer) && !(engineer) && !(scientist) ) {}

For example, I interviewed a semi fresh grad with one year work experience last Friday. I asked him to write a piece of code (in C++, because that's the language he claimed to be most comfortable with) that returns the absolute value of some 32-bit signed integer, just for warmup. He wrote a function that converts the input integer into a string and checks whether it has a negative sign, then... You know the rest.

It got even worse when I asked him to write a function that returns the value of a user-specified octet in any valid IPv4 address. This means the function should take an IPv4 address and the octet number the user wants returned. He did it in an extremely convoluted way that he even had a hard time explaining how the code works.

Needless to say, he had to write an entirely different code for IPv6. *

I passed all his code around to my coworkers after he left my office, and everyone was laughing so hard. One of them even accidentally swallowed her chewing gum.

In case anyone is curious, this one liner function gives you the absolute value of some 32-bit integer 'num':

There is another way: multiply the number by itself and return the square root of the multiplication (which will make it work with real numbers if you replace all instances of 'int' with 'double'). But the above code should suffice, given the requirement explicitly states 'some 32-bit signed integer'.

Computer Engineering/Computer Science graduates who don't understand why or how the above code works have wasted years of life studying a subject they're not even interested in.

Based on my own professional experience, more than half of 'programmers' that have formal education background in relevant fields (Computer Engineering/Computer Science) barely know how to program these days, which is sad.

This is just my observation. YMMV.

[*] OT: Have they come up with an official name to call IPv6 address parts, yet?