Just had an interesting thought. In languages like C# and Java, I know that when it comes to incrementing and decrementing, you can do a post, or pre-increment/decrement. Like this:
int a = 5;
Console.WriteLine(a++); // Would print out 5,
// And then increment a to 6
Console.WriteLine(++a); // Would then print out 7 because
// it increments a before printing it out
But, I was wondering if there is any such thing where one might do something like this:
int a = 5;
Console.WriteLine(a += 5); // Would print out 5,
// And then increment a to 10
Console.WriteLine(a =+ 5); // (Or something along those lines)
// To print out 15 at this point
Just interested and didn't really know where or how to look for the answer, so wondered if anyone on SO would know anything more about it. Thanks!
Edit: Added my question from the comments
Where exactly are a += 5 and a =+5 defined? I've never seen the second in use. Does it exist at all...? Do they compile to the same thing?
In the old days, the C language offered this syntax as a shortcut for adding or subtracting a value from a variable.
a =+ 5;
b =- 5;
But early on in the life of C, dmr (of blessed memory) and ken deprecated that syntax in favor of
a += 5;
b -= 5;
for precisely the same purpose, because it's far too easy to write b=-5 which means something entirely different from b -= 5. This "experienced" programmer remembers rewriting a bunch of code to match the new language spec.
So there has never been pre- or post- increment semantics in those constructions like there is in a++ or --b.
No. a += 5 isn't a post increment. It's an increment.
a++ is post-increment. And ++a is pre-increment.
The following prints the required results but is not exactly beautiful code:
int a = 5;
System.out.println(a+=5);
System.out.println((a+=5)-5);
System.out.println(a);
Prints:
10, 10, 15
a+=5 returns the value of a after the increment. (a+=5)-5 increments a and returns its value before the increment.
a=+5 just compiles to a=5. This performs assignment and the unary plus operator. It is akin to doing a=-5 (a equals negative 5).
System.out.println(+5);
Prints:
5
In C# the equivalent code generates the same output:
int a = 5;
Console.WriteLine(a+=5);
Console.WriteLine((a+=5)-5);
Console.WriteLine(a);
Console.WriteLine(+5);
Prints:
10, 10, 15, 5
There is no such operator in any language that I know of, but you can write your own C# function to do the same thing!
static void postAdd<T>(ref T lhs, T rhs) {
T saved = lhs;
lhs += rhs;
return saved;
}
This is not possible in Java because Java does not support pass-by-reference with ref.
Console.WriteLine(a+=5);
Is perfectly legal in the langauge. It is a sort of pre-increment operator in that it will increment the variable a before returning the value to the WriteLine call.
=+ isn't a valid operator since it isn't defined by the C# standard. All of the C# operators can be found on this page: https://msdn.microsoft.com/en-us/library/ewkkxkwb.aspx
Its not possible to create your own operators, because the compiler would have to know how to make expression trees or parse the line to generate the IL. The aside to this is that, by a lot of work and especially with the release of Rosyln, you could in theory make your own language (like IronPython) that had those operators.
The closest that you can come to your own operator are things like extension methods, for example:
public class Extensions
{
public static int AddMul(this int x, int add, int mull)
{
return x * mull + add;
}
}
which would be used like:
int x = 4;
int y = x.AddMul(2, 3); //y now equals 14
Related
Why can't do you this if you try to find out whether an int is between to numbers:
if(10 < x < 20)
Instead of it, you'll have to do
if(10<x && x<20)
which seems like a bit of overhead.
One problem is that a ternary relational construct would introduce serious parser problems:
<expr> ::= <expr> <rel-op> <expr> |
... |
<expr> <rel-op> <expr> <rel-op> <expr>
When you try to express a grammar with those productions using a typical PGS, you'll find that there is a shift-reduce conflict at the point of the first <rel-op>. The parse needs to lookahead an arbitrary number of symbols to see if there is a second <rel-op> before it can decide whether the binary or ternary form has been used. In this case, you could not simply ignore the conflict because that would result in incorrect parses.
I'm not saying that this grammar is fatally ambiguous. But I think you'd need a backtracking parser to deal with it correctly. And that is a serious problem for a programming language where fast compilation is a major selling point.
Because that syntax simply isn't defined? Besides, x < y evaluates as a bool, so what does bool < int mean? It isn't really an overhead; besides, you could write a utility method if you really want - isBetween(10,x,20) - I wouldn't myself, but hey...
It's just the syntax. '<' is a binary operation, and most languages don't make it transitive. They could have made it like the way you say, but then somebody would be asking why you can't do other operations in trinary as well. "if (12 < x != 5)"?
Syntax is always a trade-off between complexity, expressiveness and readability. Different language designers make different choices. For instance, SQL has "x BETWEEN y AND z", where x, y, and z can individually or all be columns, constants, or bound variables. And I'm happy to use it in SQL, and I'm equally happy not to worry about why it's not in Java.
You could make your own
public static boolean isBetween(int a, int b, int c) {
return b > a ? c > a && c < b : c > b && c < a;
}
Edit: sorry checks if c is between a and b
The inconvenience of typing 10 < x && x < 20 is minimal compared to the increase in language complexity if one would allow 10 < x < 20, so the designers of the Java language decided against supporting it.
COBOL allows that (I am sure some other languages do as well). Java inherited most of it's syntax from C which doesn't allow it.
You are human, and therefore you understand what the term "10 < x < 20" suppose to mean.
The computer doesn't have this intuition, so it reads it as:
"(10 < x) < 20".
For example, if x = 15, it will calculate:
(10 < x) => TRUE
"TRUE < 20" => ???
In C programming, it will be worse, since there are no True\False values.
If x = 5, the calculation will be:
10 < x => 0 (the value of False)
0 < 20 => non-0 number (True)
and therefore "10 < 5 < 20" will return True! :S
simplifying:
a = 10; b = 15; c = 20
public static boolean check(int a, int b, int c) {
return a<=b && b<=c;
}
This checks if b is between a and c
Because the < operator (and most others) are binary operators (they take two arguments), and (true true) is not a valid boolean expression.
The Java language designers could have designed the language to allow syntax like the type you prefer, but (I'm guessing) they decided that it was not worth the more complex parsing rules.
One can use Range class from the Guava library:
Range.open(10, 20).contains(n)
Apache Commons Lang has a similar class as well.
if (10 < x || x < 20)
This statement will evaluate true for numbers between 10 and 20.
This is a rough equivalent to 10 < x < 20
This question already has answers here:
How can I perform multiplication without the '*' operator?
(31 answers)
Closed 4 years ago.
I had an interesting interview yesterday where the interviewer asked me a classic question: How can we multiply two numbers in Java without using the * operator. Honestly, I don't know if it's the stress that comes with interviews, but I wasn't able to come up with any solution.
After the interview, I went home and breezed through SO for answers. So far, here are the ones I have found:
First Method: Using a For loop
// Using For loop
public static int multiplierLoop(int a, int b) {
int resultat = 0;
for (int i = 0; i < a; i++) {
resultat += b;
}
return resultat;
}
Second Method: Using Recursion
// using Recursion
public static int multiplier(int a, int b) {
if ((a == 0) || (b == 0))
return 0;
else
return (a + multiplier(a, b - 1));
}
Third Method: Using Log10
**// Using Math.Log10
public static double multiplierLog(int a, int b) {
return Math.pow(10, (Math.log10(a) + Math.log10(b)));
}**
So now I have two questions for you:
Is there still another method I'm missing?
Does the fact that I wasn't able to come up with the answer proves that my logical reasoning isn't strong enough to come up with solutions and that I'm not "cut out" to be a programmer? Cause let's be honest, the question didn't seem that difficult and I'm pretty sure most programmers would easily and quickly find an answer.
I don't know whether that has to be a strictly "programming question". But in Maths:
x * y = x / (1 / y) #divide by inverse
So:
Method 1:
public static double multiplier(double a, double b) {
// return a / (1 / b);
// the above may be too rough
// Java doesn't know that "(a / (b / 0)) == 0"
// a special case for zero should probably be added:
return 0 == b ? 0 : a / (1 / b);
}
Method 2 (a more "programming/API" solution):
Use big decimal, big integer:
new BigDecimal("3").multiply(new BigDecimal("9"))
There are probably a few more ways.
There is a method called [Russian Peasant Multiplication][1]. Demonstrate this with the help of a shift operator,
public static int multiply(int n, int m)
{
int ans = 0, count = 0;
while (m > 0)
{
if (m % 2 == 1)
ans += n << count;
count++;
m /= 2;
}
return ans;
}
The idea is to double the first number and halve the second number repeatedly till the second number doesn’t become 1. In the process, whenever the second number become odd, we add the first number to result (result is initialized as 0) One other implementation is,
static int russianPeasant(int n, int m) {
int ans = 0;
while (m > 0) {
if ((m & 1) != 0)
ans = ans + n;
n = n << 1;
m = m >> 1;
}
return ans;
}
refer :
https://www.geeksforgeeks.org/russian-peasant-multiply-two-numbers-using-bitwise-operators/
https://www.geeksforgeeks.org/multiplication-two-numbers-shift-operator/
[1]: https://web.archive.org/web/20180101093529/http://mathforum.org/dr.math/faq/faq.peasant.html
Others have hit on question 1 sufficiently that I'm not going to rehash it here, but I did want to hit on question 2 a little, because it seems (to me) the more interesting one.
So, when someone is asking you this type of question, they are less concerned with what your code looks like, and more concerned with how you are thinking. In the real world, you won't ever actually have to write multiplication without the * operator; every programming language known to man (with the exception of Brainfuck, I guess) has multiplication implemented, almost always with the * operator. The point is, sometimes you are working with code, and for whatever reason (maybe due to library bloat, due to configuration errors, due to package incompatibility, etc), you won't be able to use a library you are used to. The idea is to see how you function in those situations.
The question isn't whether or not you are "cut out" to be a programmer; skills like these can be learned. A trick I use personally is to think about what, exactly, is the expected result for the question they're asking? In this particular example, as I (and I presume you as well) learned in grade 4 in elementary school, multiplication is repeated addition. Therefore, I would implement it (and have in the past; I've had this same question in a few interviews) with a for loop doing repeated addition.
The thing is, if you don't realize that multiplication is repeated addition (or whatever other question you're being asked to answer), then you'll just be screwed. Which is why I'm not a huge fan of these types of questions, because a lot of them boil down to trivia that you either know or don't know, rather than testing your true skills as a programmer (the skills mentioned above regarding libraries etc can be tested much better in other ways).
TL;DR - Inform the interviewer that re-inventing the wheel is a bad idea
Rather than entertain the interviewer's Code Golf question, I would have answered the interview question differently:
Brilliant engineers at Intel, AMD, ARM and other microprocessor manufacturers have agonized for decades as how to multiply 32 bit integers together in the fewest possible cycles, and in fact, are even able to produce the correct, full 64 bit result of multiplication of 32 bit integers without overflow.
(e.g. without pre-casting a or b to long, a multiplication of 2 ints such as 123456728 * 23456789 overflows into a negative number)
In this respect, high level languages have only one job to do with integer multiplications like this, viz, to get the job done by the processor with as little fluff as possible.
Any amount of Code Golf to replicate such multiplication in software IMO is insanity.
There's undoubtedly many hacks which could simulate multiplication, although many will only work on limited ranges of values a and b (in fact, none of the 3 methods listed by the OP perform bug-free for all values of a and b, even if we disregard the overflow problem). And all will be (orders of magnitude) slower than an IMUL instruction.
For example, if either a or b is a positive power of 2, then bit shifting the other variable to the left by log can be done.
if (b == 2)
return a << 1;
if (b == 4)
return a << 2;
...
But this would be really tedious.
In the unlikely event of the * operator really disappearing overnight from the Java language spec, next best, I would be to use existing libraries which contain multiplication functions, e.g. BigInteger.multiply(), for the same reasons - many years of critical thinking by minds brighter than mine has gone into producing, and testing, such libraries.
BigInteger.multiply would obviously be reliable to 64 bits and beyond, although casting the result back to a 32 bit int would again invite overflow problems.
The problem with playing operator * Code Golf
There's inherent problems with all 3 of the solutions cited in the OP's question:
Method A (loop) won't work if the first number a is negative.
for (int i = 0; i < a; i++) {
resultat += b;
}
Will return 0 for any negative value of a, because the loop continuation condition is never met
In Method B, you'll run out of stack for large values of b in method 2, unless you refactor the code to allow for Tail Call Optimisation
multiplier(100, 1000000)
"main" java.lang.StackOverflowError
And in Method 3, you'll get rounding errors with log10 (not to mention the obvious problems with attempting to take a log of any number <= 0). e.g.
multiplier(2389, 123123);
returns 294140846, but the actual answer is 294140847 (the last digits 9 x 3 mean the product must end in 7)
Even the answer using two consecutive double precision division operators is prone to rounding issues when re-casting the double result back to an integer:
static double multiply(double a, double b) {
return 0 == (int)b
? 0.0
: a / (1 / b);
}
e.g. for a value (int)multiply(1, 93) returns 92, because multiply returns 92.99999.... which is truncated with the cast back to a 32 bit integer.
And of course, we don't need to mention that many of these algorithms are O(N) or worse, so the performance will be abysmal.
For completeness:
Math.multiplyExact(int,int):
Returns the product of the arguments, throwing an exception if the result overflows an int.
if throwing on overflow is acceptable.
If you don't have integer values, you can take advantage of other mathematical properties to get the product of 2 numbers. Someone has already mentioned log10, so here's a bit more obscure one:
public double multiply(double x, double y) {
Vector3d vx = new Vector3d(x, 0, 0);
Vector3d vy = new Vector3d(0, y, 0);
Vector3d result = new Vector3d().cross(vx, vy);
return result.length();
}
One solution is to use bit wise operations. That's a bit similar to an answer presented before, but eliminating division also. We can have something like this. I'll use C, because I don't know Java that well.
uint16_t multiply( uint16_t a, uint16_t b ) {
uint16_t i = 0;
uint16_t result = 0;
for (i = 0; i < 16; i++) {
if ( a & (1<<i) ) {
result += b << i;
}
}
return result;
}
The questions interviewers ask reflect their values. Many programmers prize their own puzzle-solving skills and mathematical acumen, and they think those skills make the best programmers.
They are wrong. The best programmers work on the most important thing rather than the most interesting bit; make simple, boring technical choices; write clearly; think about users; and steer away from stupid detours. I wish I had these skills and tendencies!
If you can do several of those things and also crank out working code, many programming teams need you. You might be a superstar.
But what should you do in an interview when you're stumped?
Ask clarifying questions. ("What kind of numbers?" "What kind of programming language is this that doesn't have multiplication?" And without being rude: "Why am I doing this?") If, as you suspect, the question is just a dumb puzzle with no bearing on reality, these questions will not produce useful answers. But common sense and a desire to get at "the problem behind the problem" are important engineering virtues.
The best you can do in a bad interview is demonstrate your strengths. Recognizing them is up to your interviewer; if they don't, that's their loss. Don't be discouraged. There are other companies.
Use BigInteger.multiply or BigDecimal.multiply as appropriate.
I was going through some exercises but I am confused in this one:
public static int f (int x, int y) {
int b=y--;
while (b>0) {
if (x%2!=0) {
--x;
y=y-2;
}
else {
x=x/2;
b=b-x-1;
}
}
return x+y;
}
What is the purpose of b=y--?
So, for example, x=5 and y=5
when we first go inside of while loop (while (b>0)) will b = 4 or 5? When I am running the code in my computer b is 5. And the return is 3. It is really unclear to me. Sorry if I am unclear in my question.
int b=y--; first assignes b=y and then decrements y (y--).
Also take a look at the prefix/postfix unary increment operator.
This example (taken from the linked page) demonstrates it:
class PrePostDemo {
public static void main(String[] args){
int i = 3;
i++;
// prints 4
System.out.println(i);
++i;
// prints 5
System.out.println(i);
// prints 6
System.out.println(++i);
// prints 6
System.out.println(i++);
// prints 7
System.out.println(i);
}
}
The difference between a post-increment/decrement and a pre-increment/decrement is in the evaluation of the expression.
The pre-increment and pre-decrement operators increment (or decrement) their operand by 1, and the value of the expression is the resulting incremented (or decremented) value. In contrast, the post-increment and post-decrement operators increase (or decrease) the value of their operand by 1, but the value of the expression is the operand's original value prior to the increment (or decrement) operation.
In other words:
int a = 5;
int b;
b = --a; // the value of the expression --a is a-1. b is now 4, as is a.
b = a--; // the value of the expression a-- is a. b is still 4, but a is 3.
Remember that a program must evaluate expressions to do everything. Everything is an expression, even just a casual mention of a variable. All of the following are expressions:
a
a-1
--a && ++a
System.out.println(a)
Of course, in the evaluation of expressions, operator precedence dictates the value of an expression just as the PEMDAS you learned in grade school. Some operators, such as increment/decrement, have side effects, which is of course great fun, and one of the reasons why functional programming was created.
I believe b would equal 5 entering the loop because
b=y--;
When the "--" is behind the variable it decrements it after the action.
It's poor coding, as it can confuse new programmers.
The function, assuming it is passing by value, like in the example above (as opposed to passing by reference) takes a copy of y, decrements it, and assigns it to b. It does not alter the argument passed to the function when it was called.
Post increment
x++;
x += 1;
Post decrement
x--;
x -=1;
Pre increment : ++x;
Pre decrement : --x;
According to the Head First Java:
Difference between x++ and ++x :
int x = 0; int z = ++x;
Produces: x is 1, x is 1
in x = 0; int z = x++;
Produces: x is 1, z is 0
I was asked a question what the difference is between having counter += 5 and counter + 5 in the java programming language. I said they essentially do the same thing but I did not know how to explain why. I felt one was considered a shorthand representation of the same problem but now thinking about it more, I feel I am not correct. Can anyone give me a simple explanation the difference between them?
counter += 5 modifies counter. counter += 5 can be used as a statement (e.g. line of code) on its own, because it does something (increments counter by 5).
counter + 5 does not modify anything. counter + 5 can only be used as an expression within a statement, because it doesn't do anything on its own.
Here is some code that demonstrates the difference:
int counter = 1;
System.out.println(counter + 5); // 6
System.out.println(counter); // 1
// counter + 5; // not a valid statement
counter += 5; // counter is now 6
System.out.println(counter); // 6
System.out.println(counter += 5); // 11
System.out.println(counter); // 11
counter += 5 is assigning the value of whatever counter was plus 5 to the counter variable while counter+5 is return the result of 5 plus counter but the counter variable stays the same.
+= operator
For example you have a a variable counter that equals 3. When you do counter += 5, you are actually assigning a new value to the variable counter. so if counter was 5 and you do counter+=3, counter will now equal 8.
+ operator without the equal
In this case if your counter equals 3. when you do counter+3 it will return 8 for that instance but your counter will still be 3.
Code to demonstrate the differences:
int counter = 3;
counter += 5;
int y = 0;
/*this will return 8, since the result of 5 and counter was newly assigned to
counter*/
System.out.println(counter);
//resetting counter value.
counter =3;
y = counter+5;
//here counter still remains at 3, because there wasn't anything assigned to it
System.out.println(counter);
//will return 8, because you assigned the result of counter and 5 to y.
System.out.println(y);
Only the JLS holds the true answer!
(Assuming count is a numeric type. If it's a String, for example, then everything everyone told you above is wrong at the time I wrote this.)
+= operator
JLS 15.26.2 Compound Assignment Operators:
A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T) ((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.
following,
[...] the saved value of the left-hand variable and the value of the right-hand operand are used to perform the binary operation indicated by the compound assignment operator.
[...] the result of the binary operation is converted to the type of the left-hand variable, subjected to value set conversion (§5.1.13) to the appropriate standard value set (not an extended-exponent value set), and the result of the conversion is stored into the variable.
(emphasis mine). In the above above notation, E1 and E2 will perform the operation indicated by += (meaning E1 + E2). The result is stored in E1.
+ operator
JLS 15.18.2. Additive Operators (+ and -) for Numeric Types:
The binary + operator performs addition when applied to two operands of numeric type, producing the sum of the operands.
Note that there is no assignment here.
counter += 5 is the one that is shorthand, but it's shorthand for counter = counter + 5. counter + 5 is just an expression, what you get is a value that is 5 greater than the value of counter, but this value is just left behind and nothing is done with it. In order for something else to happen, an additional operator needs to be present, such as the =, or assignment operator. This operator takes an expression on the right hand side and an identifier on the left, evaluating the expression and assigning the result to the identifier. Without assignment, values don't change, and even when you use methods that seem to change values without assignment (String.append() for example) there is an assignment hidden in the code of the function. As an added fact, counter += 5 can be reduced (if you really want to call it reducing it) to counter++ used 5 times.
Is there a Java function to convert a positive int to a negative one and a negative int to a positive one?
I'm looking for a reverse function to perform this conversion:
-5 -> 5
5 -> -5
What about x *= -1; ? Do you really want a library function for this?
x = -x;
This is probably the most trivial question I have ever seen anywhere.
... and why you would call this trivial function 'reverse()' is another mystery.
Just use the unary minus operator:
int x = 5;
...
x = -x; // Here's the mystery library function - the single character "-"
Java has two minus operators:
the familiar arithmetic version (eg 0 - x), and
the unary minus operation (used here), which negates the (single) operand
This compiles and works as expected.
Another method (2's complement):
public int reverse(int x){
x~=x;
x++;
return x;
}
It does a one's complement first (by complementing all the bits) and then adds 1 to x. This method does the job as well.
Note: This method is written in Java, and will be similar to a lot of other languages
No such function exists or is possible to write.
The problem is the edge case Integer.MIN_VALUE (-2,147,483,648 = 0x80000000) apply each of the three methods above and you get the same value out. This is due to the representation of integers and the maximum possible integer Integer.MAX_VALUE (-2,147,483,647 = 0x7fffffff) which is one less what -Integer.MIN_VALUE should be.
Yes, as was already noted by Jeffrey Bosboom (Sorry Jeffrey, I hadn't noticed your comment when I answered), there is such a function: Math.negateExact.
and
No, you probably shouldn't be using it. Not unless you need a method reference.
original *= -1;
Simple line of code, original is any int you want it to be.
Necromancing here.
Obviously, x *= -1; is far too simple.
Instead, we could use a trivial binary complement:
number = ~(number - 1) ;
Like this:
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
int iPositive = 15;
int iNegative = ( ~(iPositive - 1) ) ; // Use extra brackets when using as C preprocessor directive ! ! !...
System.out.println(iNegative);
iPositive = ~(iNegative - 1) ;
System.out.println(iPositive);
iNegative = 0;
iPositive = ~(iNegative - 1);
System.out.println(iPositive);
}
}
That way we can ensure that mediocre programmers don't understand what's going on ;)
The easiest thing to do is 0- the value
for instance if int i = 5;
0-i would give you -5
and if i was -6;
0- i would give you 6
You can use the minus operator or Math.abs. These work for all negative integers EXCEPT for Integer.MIN_VALUE!
If you do 0 - MIN_VALUE the answer is still MIN_VALUE.
For converting a negative number to positive. Simply use Math.abs() inbuilt function.
int n = -10;
n = Math.abs(n);
All the best!
In kotlin you can use unaryPlus and unaryMinus
input = input.unaryPlus()
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/unary-plus.html
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/unary-minus.html
You can use Math:
int x = Math.abs(-5);