Is it better to write
int primitive1 = 3, primitive2 = 4;
Integer a = new Integer(primitive1);
Integer b = new Integer(primitive2);
int compare = a.compareTo(b);
or
int primitive1 = 3, primitive2 = 4;
int compare = (primitive1 > primitive2) ? 1 : 0;
if(compare == 0){
compare = (primitive1 == primitive2) ? 0 : -1;
}
I think the second one is better, should be faster and more memory optimized. But aren't they equal?
For performance, it usually best to make the code as simple and clear as possible and this will often perform well (as the JIT will optimise this code best). In your case, the simplest examples are also likely to be the fastest.
I would do either
int cmp = a > b ? +1 : a < b ? -1 : 0;
or a longer version
int cmp;
if (a > b)
cmp = +1;
else if (a < b)
cmp = -1;
else
cmp = 0;
or
int cmp = Integer.compare(a, b); // in Java 7
int cmp = Double.compare(a, b); // before Java 7
It's best not to create an object if you don't need to.
Performance wise, the first is best.
If you know for sure that you won't get an overflow you can use
int cmp = a - b; // if you know there wont be an overflow.
you won't get faster than this.
Use Integer.compare(int, int). And don'try to micro-optimize your code unless you can prove that you have a performance issue.
May I propose a third
((Integer) a).compareTo(b)
Wrapping int primitive into Integer object will cost you some memory, but the difference will be only significant in very rare(memory demand) cases (array with 1000+ elements). I will not recommend using new Integer(int a) constructor this way. This will suffice :
Integer a = 3;
About comparision there is Math.signum(double d).
compare= (int) Math.signum(a-b);
They're already ints. Why not just use subtraction?
compare = a - b;
Note that Integer.compareTo() doesn't necessarily return only -1, 0 or 1 either.
For pre 1.7 i would say an equivalent to Integer.compare(x, y) is:
Integer.valueOf(x).compareTo(y);
If you are using java 8, you can create Comparator by this method:
Comparator.comparingInt(i -> i);
if you would like to compare with reversed order:
Comparator.comparingInt(i -> -i);
If you need just logical value (as it almost always is), the following one-liner will help you:
boolean ifIntsEqual = !((Math.max(a,b) - Math.min(a, b)) > 0);
And it works even in Java 1.5+, maybe even in 1.1 (i don't have one). Please tell us, if you can test it in 1.5-.
This one will do too:
boolean ifIntsEqual = !((Math.abs(a-b)) > 0);
Related
I want to extrapolate a byte array into a double array.
I know how to do it in Java. But the AS converter doesn't work for this... :-D
This is the class I want to write in Kotlin:
class ByteArrayToDoubleArrayConverter {
public double[] invoke(byte[] bytes) {
double[] doubles = new double[bytes.length / 2];
int i = 0;
for (int n = 0; n < bytes.length; n = n + 2) {
doubles[i] = (bytes[n] & 0xFF) | (bytes[n + 1] << 8);
i = i + 1;
}
return doubles;
}
}
This would be a typical example of what results are expected:
class ByteArrayToDoubleArrayConverterTest {
#Test
fun `check typical values`() {
val bufferSize = 8
val bytes = ByteArray(bufferSize)
bytes[0] = 1
bytes[1] = 0
bytes[2] = 0
bytes[3] = 1
bytes[4] = 0
bytes[5] = 2
bytes[6] = 1
bytes[7] = 1
val doubles = ByteArrayToDoubleArrayConverter().invoke(bytes)
assertTrue(1.0 == doubles[0])
assertTrue(256.0 == doubles[1])
assertTrue(512.0 == doubles[2])
assertTrue(257.0 == doubles[3])
}
}
Any idea? Thanks!!!
I think this would be clearest with a helper function. Here's an extension function that uses a lambda to convert pairs of bytes into a DoubleArray:
inline fun ByteArray.mapPairsToDoubles(block: (Byte, Byte) -> Double)
= DoubleArray(size / 2){ i -> block(this[2 * i], this[2 * i + 1]) }
That uses the DoubleArray constructor which takes an initialisation lambda as well as a size, so you don't need to loop through setting values after construction.
The required function then simply needs to know how to convert each pair of bytes into a double. Though it would be more idiomatic as an extension function rather than a class:
fun ByteArray.toDoubleSamples() = mapPairsToDoubles{ a, b ->
(a.toInt() and 0xFF or (b.toInt() shl 8)).toDouble()
}
You can then call it with e.g.:
bytes.toDoubleSamples()
(.toXxx() is the conventional name for a function which returns a transformed version of an object. The standard name for this sort of function would be toDoubleArray(), but that normally converts each value to its own double; what you're doing is more specialised, so a more specialised name would avoid confusion.)
The only awkward thing there (and the reason why the direct conversion from Java fails) is that Kotlin is much more fussy about its numeric types, and won't automatically promote them the way Java and C do; it also doesn't have byte overloads for its bitwise operators. So you need to call toInt() explicitly on each byte before you can call and and shl, and then call toDouble() on the result.
The result is code that is a lot shorter, hopefully much more readable, and also very efficient! (No intermediate arrays or lists, and — thanks to the inline — not even any unnecessary function calls.)
(It's a bit more awkward than most Kotlin code, as primitive arrays aren't as well-supported as reference-based arrays — which are themselves not as well-supported as lists. This is mainly for legacy reasons to do with Java compatibility. But it's a shame that there's no chunked() implementation for ByteArray, which could have avoided the helper function, though at the cost of a temporary list.)
I have a quick question on an assignment I'm trying to finish up. I'm writing a boolean method that takes three digit parameters (0-9) and returns true if they can be re arranged to make up a sequence. The hard part, for me at least, is that 0 can make a sequence with 8, 9, or 1,2. The three numbers are assumed to all be different. To be clear, the number 5,7,6 would be true because it can be rearranged to be 5, 6, 7, a sequence. Also 8,0,9 would return true, but 2,4,7 would not. I'm hoping someone can point me in the right direction with this, any help at all would be much appreciated!
You only need to check the validity of two tests:
Are all numbers different?
Is the absolute difference between the extremes 2?
This would give you the following method:
public static boolean isSequence(int a, int b, int c) {
if(a == 0) a = 10;
if(b == 0) b = 10;
if(c == 0) c = 10;
//Add the commented-out lines to make it safe to use with non-different numbers.
//boolean allDifferent = !(a == b) && !(b == c) && !(a == c);
boolean extremesIsTwo = Math.abs(Math.max(Math.max(a, b), c)
- Math.min(Math.min(a, b), c)) == 2;
//return allDifferent && extremesIsTwo;
return extremesIsTwo;
}
When you look at it, it's only a matter of simple logic, and finding the shortest path to the answer. There might be more optimized ways to do this, but this is clear, readable and works just fine.
Now, if you really want to get grinding on a problem of the like, you could either try to optimize this algorithm, or find another way to check that the three numbers are a sequence.
EDIT This version is scalable. And even though your requirements are for three arguments, I would still consider this solution, because it uses OOP to avoid repetition of code. As requested, it also doesn't check for duplicates.
public static boolean isSequenceScalable(List<Integer> list) {
list = list.stream().map(i -> i = (i == 0) ? 10 : i).collect(Collectors.toList());
list.sort(Integer::compareTo);
if (Math.abs(list.get(0) - list.get(list.size() - 1)) == 2) return true;
return false;
}
I can calculate the multiplication of two BigIntegers (say a and b) modulo n.
This can be done by:
a.multiply(b).mod(n);
However, assuming that a and b are of the same order of n, it implies that during the calculation, a new BigInteger is being calculated, and its length (in bytes) is ~ 2n.
I wonder whether there is more efficient implementation that I can use. Something like modMultiply that is implemented like modPow (which I believe does not calculate the power and then the modulo).
I can only think of
a.mod(n).multiply(b.mod(n)).mod(n)
and you seem already to be aware of this.
BigInteger has a toByteArray() but internally ints are used. hence n must be quite large to have an effect. Maybe in key generation cryptographic code there might be such work.
Furhtermore, if you think of short-cutting the multiplication, you'll get something like the following:
public static BigInteger multiply(BigInteger a, BigInteger b, int mod) {
if (a.signum() == -1) {
return multiply(a.negate(), b, mod).negate();
}
if (b.signum() == -1) {
return multiply(a, b.negate(), mod).negate();
}
int n = (Integer.bitCount(mod - 1) + 7) / 8; // mod in bytes.
byte[] aa = a.toByteArray(); // Highest byte at [0] !!
int na = Math.min(n, aa.length); // Heuristic.
byte[] bb = b.toByteArray();
int nb = Math.min(n, bb.length); // Heuristic.
byte[] prod = new byte[n];
for (int ia = 0; ia < na; ++ia) {
int m = ia + nb >= n ? n - ia - 1 : nb; // Heuristic.
for (int ib = 0; ib < m; ++ib) {
int p = (0xFF & aa[aa.length - 1 - ia]) * (0xFF & bb[bb.length - 1 - ib]);
addByte(prod, ia + ib, p & 0xFF);
if (ia + ib + 1 < n) {
addByte(prod, ia + ib + 1, (p >> 8) & 0xFF);
}
}
}
// Still need to do an expensive mod:
return new BigInteger(prod).mod(BigInteger.valueOf(mod));
}
private static void addByte(byte[] prod, int i, int value) {
while (value != 0 && i < prod.length) {
value += prod[prod.length - 1 - i] & 0xFF;
prod[prod.length - 1 - i] = (byte) value;
value >>= 8;
++i;
}
}
That code does not look appetizing. BigInteger has the problem of exposing the internal value only as big-endian byte[] where the first byte is the most significant one.
Much better would be to have the digits in base N. That is not unimaginable: if N is a power of 2 some nice optimizations are feasible.
(BTW the code is untested - as it does not seem convincingly faster.)
First, the bad news: I couldn't find any existing Java libraries that provided this functionality.
I couldn't find any pure-Java big integer libraries ... apart from java.math.BigInteger.
There are Java / JNI wrappers for the GMP library, but GMP doesn't implement this either.
So what are your options?
Maybe there is some pure-Java library that I missed.
Maybe there some other native (C / C++) big integer library supports this operation ... though you may need to write your own JNI wrappers.
You should be able to implement such a method for yourself, by copying the source code of java.math.BigInteger and adding an extra custom method. Alternatively, it looks like you could extend it.
Having said that, I'm not sure that there is a "substantially faster" algorithm for computing a * b mod n in Java, or any other language. (Apart from special cases; e.g. when n is a power of 2).
Specifically, the "Montgomery Reduction" approach wouldn't help for a single multiplication step. (The Wikipedia page says: "Because numbers have to be converted to and from a particular form suitable for performing the Montgomery step, a single modular multiplication performed using a Montgomery step is actually slightly less efficient than a "naive" one.")
So maybe the most effective way to speedup the computation would be to use the JNI wrappers for GMP.
You can use generic maths, like:
(A*B) mod N = ((A mod N) * (B mod N)) mod N
It may be more CPU intensive, but one should choose between CPU and memory, right?
If we are talking about modular arithmetic then indeed Montgomery reduction may be what you need. Don't know any out of box solutions though.
You can write a BigInteger multiplication as a standard long multiplication in a very large base -- for example, in base 2^32. It is fairly straightforward. If you want only the result modulo n, then it is advantageous to choose a base that is a factor of n or of which n is a factor. Then you can ignore all but one or a few of the lowest-order result (Big)digits as you perform the computation, saving space and maybe time.
That's most practical if you know n in advance, of course, but such pre-knowledge is not essential. It's especially nice if n is a power of two, and it's fairly messy if n is neither a power of 2 nor smaller than the maximum operand handled directly by the system's arithmetic unit, but all of those cases can be handled in principle.
If you must do this specifically with Java BigInteger instances, however, then be aware that any approach not provided by the BigInteger class itself will incur overhead for converting between internal and external representations.
Maybe this:
static BigInteger multiply(BigInteger c, BigInteger x)
{
BigInteger sum = BigInteger.ZERO;
BigInteger addOperand;
for (int i=0; i < FIELD_ELEMENT_BIT_SIZE; i++)
{
if (c.testBit(i))
addOperand = x;
else
addOperand = BigInteger.ZERO;
sum = add(sum, addOperand);
x = x.shiftRight(1);
}
return sum;
}
with the following helper functions:
static BigInteger add(BigInteger a, BigInteger b)
{
return modOrder(a.add(b));
}
static BigInteger modOrder(BigInteger n)
{
return n.remainder(FIELD_ORDER);
}
To be honest though, I'm not sure if this is really efficient at all since none of these operations are performed in-place.
I hacked up a recursive function in Java for a homework problem in my Stats class, that looked something like this:
public static int d (int k, int n) {
if (n == 1) return 1;
else if (n > k) return 0;
else return n*d(k-1, n) + n*d(k-1,n-1);
}
I then plugged (20, 8) into this function, and got 998,925,952. My professor, however, said that this answer was wrong, and after rethinking my code over and over again, I decided to try the same thing in Matlab:
function t = d(k,n)
t = 0;
if n == 1
t = 1;
elseif n > k
t = 0;
else
t = n*d(k-1, n) + n*d(k-1, n-1);
end
This function, apparently, gave me the right answer with the above input, 6.1169 * 10^17.
This has been bugging me all day, and I have absolutely no idea why two seemingly identical programs in two different languages would give me completely different results. Can anyone help explain this?
Your Matlab routine is probably working on floating-point input, so it will compute in floating-point.
Your Java routine has integer types; 6.1169e17 is way outside the supported range, so it overflows. Try changing your types to float or double.
611692004959217300 is much larger than 2147483647 which is the integer MAX_VALUE in Java.
I got 611692004959217300 by running
function d (k, n) {
if (n == 1) return 1;
else if (n > k) return 0;
else return n*d(k-1, n) + n*d(k-1,n-1);
}
console.log(d(20,8));
in Firebug.
Consider what the maximum value an int can have, which is what you've got in Java. Now consider what the maximum value a double can have, which is MATLAB's default type.
Java integers are 4 bytes in size, so the number looks too big (greater than 2^31). You should try again using "long" or "double" as datatype for your variables.
When you have a circular buffer represented as an array, and you need the index to wraparound (i.e., when you reach the highest possible index and increment it), is it "better" to:
return (++i == buffer.length) ? 0: i;
Or
return ++i % buffer.length;
Has using the modulo operator any drawbacks? Is it less readable than the first solution?
EDIT:
Of course it should be ++i instead of i++, changed that.
EDIT 2:
One interesting note: I found the first line of code in ArrayBlockingQueue's implementation by Doug Lea.
Update: OP has admitted in a comment that it should have been pre-increment instead. Most of the other answers missed this. There lies proof that the increment in this scenario leads to horrible readability: there's a bug, and most people couldn't see it.
The most readable version is the following:
return (i == buffer.length-1) ? 0 : i+1;
Using ++ adds unnecessary side effect to the check (not to mention that I strongly feel that you should've used pre-increment instead)
What's the problem with the original code? Let's have a look, shall we?
return (i++ == N) ? 0 : i; // OP's original, slightly rewritten
So we know that:
i is post-incremented, so when i == N-1 before the return statement, this will return N instead of wrapping to 0 immediately
Is this intended? Most of the time, the intent is to use N as an exclusive upper bound
The variable name i suggests a local variable by naming convention, but is it really?
Need to double check if it's a field, due to side-effect
In comparison:
return (i == N-1) ? 0 : i+1; // proposed alternative
Here we know that:
i is not modified, doesn't matter if it's local variable or field
When i == N-1, the returned value is 0, which is more typical scenario
The % approach
Alternatively, you can also use the % version as follows:
return (i+1) % N;
What's the problem with %? Well, the problem is that even though most people think it's the modulo operator, it's NOT! It's the remainder operator (JLS 15.17.3). A lot of people often get this confused. Here's a classic example:
boolean isOdd(int n) {
return (n % 2) == 1; // does this work???
}
That code is broken!!! It returns false for all negative values! The problem is that -1 % 2 == -1, although mathematically -1 = 1 (mod 2).
% can be tricky, and that's why I recommend the ternary operator version instead. The most important part, though, is to remove the side-effect of the increment.
See also
Wikipedia: modulo operation
Don't ask me to choose between two options which both contain postincrement (*) mixed with expression evaluation. I'll say "none".
(*) Update: It was later fixed to preincrement.
Wouldn't the i++ % buffer.length version have the drawback that it keeps incrementing i, which could lead to it hitting some sort of max_int/max_long/max_whatever limit?
Also, I would split this into
i = (i++ == buffer.length) ? 0 : i;
return i;
since otherwise you'd most likely have a bug.
The first one will give you an ArrayIndexOutOfBoundsException because i is never actually reset to 0.
The second one will (probably) give you an overflow error (or related undesirable effect) when i == Integer.MAX_VALUE (which might not actually happen in your case, but isn't good practice, IMHO).
So I'd say the second one is "more correct", but I would use something like:
i = (i+1) % buffer.length;
return i;
Which I think has neither of the two problems.
I went ahead and tested everyone's code, and was sad to find that only one of the previous posts (at the time of this post's writing) works. (Which one? Try them all to find out! You might be surprised!)
public class asdf {
static int i=0;
static int[] buffer = {0,1,2};
public static final void main(String args[]){
for(int j=0; j<5; j++){
System.out.println(buffer[getIndex()]);
}
}
public static int getIndex(){
// return (++i == buffer.length) ? 0: i;
// return ++i % buffer.length;
// i = (i++ == buffer.length) ? 0 : i;
// return i;
// i++;
// if (i >= buffer.length)
// {
// i = 0;
// }
// return i;
// return (i+1 == buffer.length) ? 0 : i+1;
i = (i+1) % buffer.length;
return i;
}
}
Expected output is:
1
2
0
1
2
Apologies in advance if there's a coding error on my part and I accidentally insult someone! x.x
PS: +1 for the previous comment about not using post-increment with equality checks (I can't actually upmod posts yet =/ )
I prefer the condition approach even if we use unsigned type, modulo operation has drawbacks. Using modulo has a bad side effect when the number tested rolls back to zero
Example:
255 % 7 == 3
So if you use byte (unsigned char) for example, when the number roll after 255 (i.e. zero), it will not result to 4. Should result to 4 (when 256 % 7), so it rotates correctly. So just use testing(if and ternary operator) constructs for correctness
If for achieving performance, and if the number is multiple of 2 (i.e. 2, 4, 8, 16, 32, 64, ...), use & operator.
So if the buffer length is 16, use:
n & 15
If buffer length is 64, use 63:
n & 63
Those rotate correctly even if the number goes back to zero. By the way, if the number is multiple of 2, even the modulo/remainder approach would also fit the bill, i.e. it will rotate correctly. But I can hazard a guess that & operation is faster than % operation.
I think the second solution has the clear advantage that it works, whereas the first does not. The first solution will always return zero when i becomes bigger than buffer.length because i is never reset.
The modulo operator has no drawbacks.
Surely it would be more readable to use an if:
i++;
if (i >= buffer.length)
{
i = 0;
}
return i;
Depends a bit if buffer.length ever changes.
This is very subjective and depends on what your colleagues are used to see. I would personally prefer the first option, as it expresses explicitly what the code does, i.e. if the buffer length is reached, reset to 0. You don't have to perform any mathematical thinking or even know what the modulo does (of course you should! :)
Personally, I prefer the modulo approach. When I see modulo, I immediately think of range limiting and looping but when I see the ternary operator, I always want to think more carefully about it simply because there are more terms to look at. Readability is subjective though, as you already pointed out in your tagging, and I suspect that most people will disagree with my opinion.
However, performance is not subjective. Modulo implies a divison operation which is often slower than a comparison against zero. Obviously, this is more difficult to determine in Java since we're not compiling to native code until the jitter kicks in.
My advice would be write which ever you feel is most appropriate (so long as it works!) and get a colleague (assuming you have one) to asses it. If they disagree, ask another colleague - then go with the majority vote. #codingbydemocracy
It is also worth noting, that if our buffer has length of power of 2 then very efficient bit manipulation will work:
idx = (idx + 1) & (length - 1)
You can use also bit manipulation:
idx = idx & ((idx-length)>>31)
But it's not faster than the if-variant on my machine.
Here is some code to compare running time in C#:
Stopwatch sw = new Stopwatch();
long cnt = 0;
int k = 0;
int modulo = 10;
sw.Start();
k = 0;
cnt = 0;
for ( int j=0 ; j<100000000 ; j++ ) {
k = (k+1) % modulo;
cnt += k;
}
sw.Stop();
Console.WriteLine( "modulo cnt=" + cnt.ToString() + " " + sw.Elapsed.ToString() );
sw.Reset();
sw.Start();
k = 0;
cnt = 0;
for (int j = 0; j < 100000000; j++) {
if ( ++k == modulo )
k = 0;
cnt += k;
}
sw.Stop();
Console.WriteLine( "if cnt=" + cnt.ToString() + " " + sw.Elapsed.ToString() );
sw.Reset();
sw.Start();
k = 0;
cnt = 0;
for (int j = 0; j < 100000000; j++) {
++k;
k = k&((k-modulo)>>31);
cnt += k;
}
sw.Stop();
Console.WriteLine( "bit cnt=" + cnt.ToString() + " " + sw.Elapsed.ToString() );
The Output:
modulo cnt=450000000 00:00:00.6406035
if cnt=450000000 00:00:00.2058015
bit cnt=450000000 00:00:00.2182448
I prefer the modulo operator for the simple reason it is shorter. And any program should be able to dream in modulo since it is almost as common as a plus operator.