Random Problem

Discussion of challenges you have already solved
Post Reply
klavierspieler21
Posts: 16
Joined: Fri Jul 13, 2007 12:21 am
Location: Waterloo

Random Problem

Post by klavierspieler21 »

I don't know Java much... I did mostly Scheme, and a bit of C.
Anybody care to explain why -2^31 failed?

Thx
klavierspieler21
Posts: 16
Joined: Fri Jul 13, 2007 12:21 am
Location: Waterloo

Post by klavierspieler21 »

re:
gfoot
Posts: 269
Joined: Wed Sep 05, 2007 11:34 pm
Location: Brighton, UK

Post by gfoot »

The challenge is to find the specific number the JVM would have printed - not just any number that passes the test. It depends on the order of generation of numbers by Java's random number generator.
klavierspieler21
Posts: 16
Joined: Fri Jul 13, 2007 12:21 am
Location: Waterloo

Post by klavierspieler21 »

i think you've mistaken with another challenge

public int bucketFromRandom(int randomNumber) {
int a[] = new int[10];
for (int i = 0; i < a.length; i++)
a = i * randomNumber;
int index = Math.abs(randomNumber) % a.length;
return a[index];
}

this has no reference to an actual random number. i just tried every int value possible, and -2^31 gave me an error, which i don't know why it's the answer.
gfoot
Posts: 269
Joined: Wed Sep 05, 2007 11:34 pm
Location: Brighton, UK

Post by gfoot »

Oh I see, sorry, I did get mixed up.

The reason for the error is that although -2^31 can be represented in an int, 2^31 cannot. So it's an error to call Math.abs on -2^31.
User avatar
SinistraD
Posts: 89
Joined: Sun Aug 16, 2009 8:39 am
Location: find me
Contact:

Post by SinistraD »

Thank you gfoot, I just couldn't get what's wrong with it, but now is all clear.
User avatar
PainKeeper
Posts: 4
Joined: Tue Jul 19, 2011 7:30 pm
Location: Germany

Post by PainKeeper »

i did it with this little code sniped. there some smaller / better way to do?
im not some java pro.

[code]
class Box
{
int zahl;
Box(int randomNumber) { zahl = randomNumber; }

int value() {
int a[] = new int[10];
for (int i = 0; i < a.length; i++)
a[i] = i * zahl;
int index = Math.abs(zahl) % a.length;
try { return a[index]; } catch (ArrayIndexOutOfBoundsException e)
{ System.out.println("Exeption: " + zahl); }
return a[index];
}

public static void main(String[] args)
{
int vol;
for ( int faktor = 1; faktor <= Integer.MAX_VALUE; faktor ++ ) {
Box myTest1 = new Box (faktor);
vol = myTest1.value();
}

}
}
[/code]

javac filename.class
java Box

output:

[quote]
Exeption: -2147483648
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -8
at Box.value(rndtest.java:12)
at Box.main(rndtest.java:20)
[/quote]
DaymItzJack
Posts: 106
Joined: Thu Oct 29, 2009 9:21 pm

Post by DaymItzJack »

PainKeeper wrote:i did it with this little code sniped. there some smaller / better way to do?
im not some java pro.
Knowing what gfoot said and putting in the value.

Also just looping from Integer.MIN_VALUE all the way to Integer.MAX_VALUE and doing Math.abs() is probably the easiest way.
moose
Posts: 67
Joined: Fri Jul 16, 2010 7:32 pm

Post by moose »

@gfoot: Thank you very much. I simply made a for-loop over every possible input for bucketFromRandom, but I couldn't guess whats wrong.
rain1024
Posts: 27
Joined: Sat Jul 23, 2011 5:20 pm

Post by rain1024 »

I debug in Netbeans IDE 7.0.1. And I found that this exception appear when
[1] int index = Math.abs(randomNumber) % a.length;
[2] return a[index];
with randomNumber = Integer.MIN_VALUE -> index = - 8 (I don't know why)
so exception appear when try access a[-8]
harvestsnow
Posts: 8
Joined: Mon Nov 21, 2011 9:15 pm

Post by harvestsnow »

Hello,

I suppose Math.abs(x) returns -x if x is negative and x otherwise.
In two's complement, -x is the same as ~x+1 (inverse all the bits of x and add 1).
But -2^31 is represented by 0x80000000; it stays the same when you apply the algorithm, as 0 does.
So --2^31 is still -2^31.
And as gfoot said, +2^31 has no possible representation in 32 bits two's complement system.
You can verify it with this code:

Code: Select all

public class Abs{
        public static void main(String args[]){
                if(args.length!=1){
                        System.out.println("Usage: java Abs number");
                        return;
                }
                int i=Integer.parseInt(args[0]);
                System.out.println("Input: " + i);
                System.out.println("Absolute: " + Math.abs(i));
                System.out.println("Negative: " + (-i));
        }
}
Add to that, the modulo operation keeps the sign of the left operand, and you have your answer.

I brute-forced it too, by the way.
avrrobot
Posts: 51
Joined: Fri Mar 04, 2011 2:54 pm
Location: Germany

Post by avrrobot »

Just googled the specs of Math.abs.
Post Reply