fibonacci works in python but fails in Java - java

I have this code for calculating fibonacci number in python. It works and gives the expected result. but when I translated the same to Java, it fails. Any idea of what is going wrong here?
In python:
def fib3(n):
a,b=0,1
while n>0:
a,b=b,a+b
n-=1
return a
fib3(12) --> 144
In Java:
public static int fib2(int n){
int a = 0;
int b =1;
while(n-- >0){
a=b;
b=a+b;
}
return a;
}
fib2(12) --> 2048

In this section:
a=b;
b=a+b;
you're assigning b to a+b, but a is already b. So really you're doubling b
Easiest solution is a temp variable:
public static int fib2(int n){
int a = 0;
int b =1;
while(n-- >0){
int old_a;
old_a = a;
a=b;
b=old_a+b;
}
return a;
}
In python, a, b = b, a + b stores an intermediate tuple automatically before assigning the new values to the variables, while in Java you need to be explicit about it
Breaking down Python's instructions, a, b = b, a + b is executing this disassembly:
5 17 LOAD_FAST 1 (b)
20 LOAD_FAST 0 (a)
23 LOAD_FAST 1 (b)
26 BINARY_ADD
27 ROT_TWO
28 STORE_FAST 0 (a)
31 STORE_FAST 1 (b)
In a simpler sense, staying python, here's the process:
temp_tuple = (b, a + b)
a, b = temp_tuple

The issue is that you've got to one value from b to a at the same time as assigning to b the sum of a and b. Get that simultaneous swap wrong and you get the wrong answer.
In the spirit of the Python code, I present:
public static int fib(int n) {
int a = 0, b = 1;
while (n-->0)
b = a + (a = b);
return a;
}
This does the swap effectively at the same time as the add (strictly not, but it's good enough). Note that this is well-defined Java, as the language defines the evaluation order of operators precisely, unlike in C and C++ (where the equivalent of the above code is permitted to make demons fly out of your nose due to being Undefined Behavior).
OK, if it did make you experience problems with nasal demons, I'd suggest not using that compiler in future. But you wouldn't have any assurance of getting a correct fib() function…

a = b;
b = a+b;
This computes b = 2*b because a's value is overwritten by the time you compute the new value for b. Replace it with:
t = b;
b = a+b;
a = t

a=b;
b=a+b;
... is the problem. You need to save the old value of a before adding it to b.

The code is not equivalent, and relies on python's ability to assign multiple primitives in one line a,b=b,a+b; you need a temporary variable -
public static int fib2(int n){
int a = 0;
int b =1;
while(n-- >0){
int t = b; // <-- to hold the original value of b.
b = a + b;
a = t;
}
return a;
}

In java - When you write "a=b; b=a+b;" you are essentially saying that a should be equal to be and then that (since 'a' is now equal to 'b') that 'b' should just be twice what it originally was.
There are two ways you can fix this.
1) You can either continue the function you are originally using and then create a int 'temp' to store 'a' before you change 'a'.
2) You can also do what I would rather do ( this will use a lot more time however for a algorithm like fibonacci and would generally be a terrible idea for real world applications) is use a recursive function that will call itself.
It would generally look something like the following.
public static int fib2(int n){
if(n<=0){return 0;}
if(n<2){return 1;}
else{ return fib2(n-1)+fib2(n-2);}
}
That would probably not be the exact code but something very similar. Hope that was helpful!

Related

Scope of variable instantiated inside a method - Java

Is this code safe in Java?
public class HelloWorld {
public static void main (String args[]) {
HelloWorld h = new HelloWorld();
int y = h.getNumber(5);
int z = h.getNumber (6);
if (y == 10)
System.out.println("true");
}
public int getNumber(int x) {
int number = 5;
number = number + x;
return number;
}
}
My co-worker says that int number will be placed on the stack and when getNumber returns it will be popped off and could potentially be overwritten.
Is the same code potentially unsafe in C?
The HelloWorld class has no fields, and is therefore immutable. You can call your getNumber(x) function as many times as you'd like, from any thread, using the same object, and it will always give the same result for the same argument.
Maybe your co-worker is recalling horror stories in C where you can have something like static int number, which "belongs" to the method and which would get overwritten. Or maybe she's thinking about "return by reference"; even if it were, you'd be referencing a brand-new object every time because number is newly instantiated for every method call.
Your coworker is correct, sort of, but they apparently misunderstand what is going on.
public int getNumber(int x) {
int number = 5;
number = number + x;
return number;
}
Yes the value of 5 + 5 or 5 + 6 will be placed on the stack, but there is no danger of them being overwritten, they will properly be placed into y or z.
I suspect the confusion is from C (this type code works fine in C as well), but for pointers instead of primitives. Returning a result of malloc from a function in C can be "challenging" if you don't do it right.

How this type of expression works [duplicate]

This question already has answers here:
What is the Java ?: operator called and what does it do?
(17 answers)
Closed 7 years ago.
Can anybody tell me how the snippet below will be executed?
Code:-
int a = 3, b = 4;
a = (a > b) ? a : b;
System.out.print(a);
It is the same as
int a = 3;
int b = 4;
if(a > b) {
a = a;
} else {
a = b;
}
System.out.print(a);
Also see
What is the Java ?: operator called and what does it do?
This is a ternary operator (note: not particular to Java but it's widespread and implemented in many languages), and returns either the 2nd or 3rd argument depending on the result of the initial condition.
result = condition ? result if true : result if false
and as such it's shorthand for
if (condition) {
return a;
}
else {
return b;
}
The value of a variable often depends on whether a particular boolean expression is or is not true and on nothing else. For instance one common operation is setting the value of a variable to the maximum of two quantities. In Java you might write
if (a > b) {
max = a;
}
else {
max = b;
}
Setting a single variable to one of two states based on a single condition is such a common use of if-else that a shortcut has been devised for it, the conditional operator, ?:. Using the conditional operator you can rewrite the above example in a single line like this:
max = (a > b) ? a : b;
(a > b) ? a : b; is an expression which returns one of two values, a or b. The condition, (a > b), is tested. If it is true the first value, a, is returned. If it is false, the second value, b, is returned. Whichever value is returned is dependent on the conditional test, a > b. The condition can be any expression which returns a boolean value.
line 1: a and b are defined.
line 2: a is set to the value of b (because 3 is not bigger than 4).
line 3: a is printed to current std out.
If 'a' is greater than 'b' you'll get a = a, otherwise if 'b' is greater than 'a' you'll get a = b.
It is the same as the following:
int a = 3, b = 4;
if(a > b){
a = a;
}else{
a = b;
}
System.out.print(a);
And that could be rewritten as:
int a = 3, b = 4;
if(a <= b){
a = b;
}
System.out.print(a);
The ? is the ternary operator, which considers the code before as condition and evaluates the code before the : is it is true, and the code after : if it is false.

Custom functions in Processing Language

doing some uni work on 'Processing' Programming language (a form of java).
So my question is 'Write a function called twoNumbers(int a,int b) which takes in two parameters a and b. If a is greater than b, then the two numbers are added together and the string 'the sum of a and b is sum' is displayed in the console window, where a and b and the sum are the values of a, b and their sum. Finally, the function should return the sum.'
..soo here is my attempt at the code, if I put (int a,int b) after the customer function, it just says that my other int a = number, is a duplicate, which is true, but im not sure how I am ment to give a and b a number without it thinking its a duplicate? Should I be putting it out of a void setup tag? as im unsure if this would then cause too many { brackets...
/* Question 1 */
int twoNumbers(){
int a = 30;
int b = 20;
if (a > b) {println(a+b);}
println("The sum of a and b is sum");
int sum;
sum = a+b;
println(sum);
}
Any help would be massively helpful in getting this and the other questions done :)
Thanks!!
Also your function is not returning a value, which will give you an error. It looks like you are confusing things. Either declare it a void or return a value of declared type (that last is what your assignment calls for). Either way a function, or a method, needs to be called to execute, and you are not calling it! So the code inside your the function is not being run!!
The following:
void imAMethod()
{
println("hello");
}
It is a valid method, but will do nothing, you need to call it, like:
imAMethod();// calling your method
void imAMethod()
{
println("hello");
}
But this won't work also, will give you the error "It looks like you're mixing "active" and "static" modes". Thats because to use a function in Processing you need to have at least a setup() method in the sketch, so:
void setup()
{
imAMethod();
}//end of setup
void imAMethod()
{
println("hello");
}
will work as expected.
But you need a function, so as Jesper pointed you will have to do something like:
int a = 30; // those are global variables to pass to your function
int b = 20;
void setup()// this is a builtin basic Processing method
{
//call your function
println("The sum of " + a + " and " + b + " is "+ twoNumbers(a, b));
}
int twoNumbers(int a, int b)
{
//do your math and tests here
return result;
}
There is another thing not clear in the assignment. A function must return something, so it is not clear what the function should return if a is not greater than b. You will have to handle this case, or compiler will complain. You may want to move this test out of the function to make things easier, like:
if (a < b)
println("The sum of " + a + " and " + b + " is "+ twoNumbers(a, b));//call your function
else
println(a + " is smaller than " + b);
and in the function just do the sum. But this may be not what the assignment requires... Anyway you will need to return something even if a is not greater than b. Note that the printing to console can be done inside the function also.
Hummm, re reading the assignment a think what is expected is: Aways return the sum, and just print if a is greater than b, which makes more sense and is easier, something like:
int twoNUmbers(int a, int b)
{
if (a < b){/*print the string*/}
return a + b;
}
Just a note for jlordo. In Processing.org you don't have a main, or better, it is transparent/hidden from user. Processing is like a "dialect" of java. So the code above would run as it is. There are two basic builtin functions: setup() and draw(). If the user do not use none of them the IDE will warps it in a setup() function, that will call the main() somewhere else. It will run once. Draw() instead loops forever.
'Write a function called twoNumbers(int a,int b) which takes in two parameters a and b.
That's not what your code looks like. Your method twoNumbers doesn't take two parameters a and b. Your code should start like this (exactly as mentioned in the assignment):
int twoNumbers(int a, int b) {
Remove the next two lines, int a = 30; and int b = 20;. Those lines declare two local variables named a and b. You should use the a and b that are passed in as parameters instead.
This also looks wrong:
if (a > b) {println(a+b);}
println("The sum of a and b is sum");
Carefully look at what the assignment says:
If a is greater than b, then the two numbers are added together and the string 'the sum of a and b is sum' is displayed in the console window, where a and b and the sum are the values of a, b and their sum.
That's not what your code is doing. Take it step by step, carefully think about what is meant in the assignment.

What does it mean for an expression to contain "at most one side effect, as its outermost operation"?

In Java Language Spex 15.7:
Code is usually clearer when each expression contains at most one side
effect, as its outermost operation
What does it mean?
It means that each expression should do one task at a time.
Consider the following two declarations:
int a = 10;
int b = 20;
Now the task is to add these two ints and increment b by 1. There are two way to do it.
int c = a + b++;
and
int c = a + b;
b++;
JLS prefers and recommends the latter one.
What this means is that:
int x = someFunction(a, b);
is clearer when someFunction(a, b) doesn't have any side-effect i.e. it doesn't change anything. Rather the only change in the above is the assignment to x.
Another example would be use of prefix/postfix incrementers.
int x = a + b;
is clearer than
int x = (a++) + (++b);
since only x is assigned to. In the second example a and b are changed in the same statement.
By limiting the side effects, you can more easily reason about the functioning of the code, and/or re-order statement invocations, including parallelising them e.g. in the below, if the methods don't have side-effects, then you can invoke the methods a(), b() and c() representing the arguments in any order, and/or in parallel.
int res = f(a(), b(), c());
Side-effect of an expression is mostly an assignment to variable during evaluation of the expression.
Notice the code:
int x = 5, y = 7;
while ((z = x-- + --y) > 0 ) {
console.out("What is 'z' now? " + z);
console.out("How many times will this be printed?");
}
Evaluation of the condition has 3 side-effects:
decrementing x
decrementing y
assignment to z
Looks twisted, isn't it?

Can The 5-Op Log2(Int 32) Bit Hack be Done in Java?

Just to clarify this is NOT a homework question as I've seen similar accusations leveled against other bit-hackish questions:
That said, I have this bit hack in C:
#include <stdio.h>
const int __FLOAT_WORD_ORDER = 0;
const int __LITTLE_END = 0;
// Finds log-base 2 of 32-bit integer
int log2hack(int v)
{
union { unsigned int u[2]; double d; } t; // temp
t.u[0]=0;
t.u[1]=0;
t.d=0.0;
t.u[__FLOAT_WORD_ORDER==__LITTLE_END] = 0x43300000;
t.u[__FLOAT_WORD_ORDER!=__LITTLE_END] = v;
t.d -= 4503599627370496.0;
return (t.u[__FLOAT_WORD_ORDER==__LITTLE_END] >> 20) - 0x3FF;
}
int main ()
{
int i = 25; //Log2n(25) = 4
int j = 33; //Log2n(33) = 5
printf("Log2n(25)=%i!\n",
log2hack(25));
printf("Log2n(33)=%i!\n",
log2hack(33));
return 0;
}
I want to convert this to Java. So far what I have is:
public int log2Hack(int n)
{
int r; // result of log_2(v) goes here
int[] u = new int [2];
double d = 0.0;
if (BitonicSorterForArbitraryN.__FLOAT_WORD_ORDER==
BitonicSorterForArbitraryN.LITTLE_ENDIAN)
{
u[1] = 0x43300000;
u[0] = n;
}
else
{
u[0] = 0x43300000;
u[1] = n;
}
d -= 4503599627370496.0;
if (BitonicSorterForArbitraryN.__FLOAT_WORD_ORDER==
BitonicSorterForArbitraryN.LITTLE_ENDIAN)
r = (u[1] >> 20) - 0x3FF;
else
r = (u[0] >> 20) - 0x3FF;
return r;
}
(Note it's inside a bitonic sorting class of mine...)
Anyhow, when I run this for the same values 33 and 25, I get 52 in each cases.
I know Java's integers are signed, so I'm pretty sure that has something to do with why this is failing. Does anyone have any ideas how I can get this 5-op, 32-bit integer log 2 to work in Java?
P.S. For the record, the technique is not mine, I borrowed it from here:
http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogIEEE64Float
If you're in Java, can't you simply do 31 - Integer(v).numberOfLeadingZeros()? If they implement this using __builtin_clz it should be fast.
I think you did not get the meaning of that code. The C code uses a union - a struct that maps the same memory to two or more different fields. That makes it possible to access the storage allocated for the double as integers. In your Java code, you don't use an union but two different variables that are mapped to different parts of memory. This makes the hack fail.
As Java has no unions, you had to use serialization to get the results you want. Since that is quite slow, why not use another method to calculate the logarithm?
You are using the union to convert your pair of ints into a double with the same bit pattern. In Java, you can do that with Double.longBitsToDouble, and then convert back with Double.doubleToLongBits. Java is always (or at least gives the impression of always being) big-endian, so you don't need the endianness check.
That said, my attempt to adapt your code into Java didn't work. The signedness of Java integers might be a problem.

Categories

Resources