int i, j, c;
double d;
short s;
long l;
float f;
boolean b;
For each expression below, if it is syntactially lega Java, indicate its type (not its value). If it is not syntactically valid, indicate why.
6
is type int
.
24L
is type long
.
+3.5
is type double
.
3.5f
is type float
.
2e-16
is type double
.
-25b
is not valid Java. b
is not a
valid suffix.
i
is type int
.
i+3
is type int
.
i+3.0
is type double
.
i+s
is type int
.
l+d
is type double
.
f+s
is type float
.
i / 0
is not valid Java. You cannot divide by zero.
4 * 3.2
is type double
.
i = 0
is type int
.
i == 0
is type boolean
.
b = 0
is not valid Java. A boolean cannot have value 0.
b == 0
is not valid Java. You cannot compare a boolean to an int.
'c'
is type char
.
"An expression in double-quotes"
is type String
.
x + 1
(x > 5) && (x < 15)
x / 2.0
x % 7L
!b
(x % 5) == 0
Console.readln()
d
be after each of the following statements? Also, indicate any other changes that may occur as a result of executing the statement. You may assume that they are executed in the order given.
double d = 3.5;
d
is 3.5
.
d = d * 3;
d
is 10.5
.
if (d < 8 )
{
Console.println( "d is pretty small" );
}
The value of d
remains 10.5
. The code inside the if
block is not executed.
d = 2.0
d
is 2.0
.
while ( d < 30 )
{
d = d * 2;
}
At the beginning of the while loop, the value of d
is 2.0
. The code inside the block is executed 4 times. Then the while
condition is false and the loop exits. d
was doubled 4 times, so its final value is 32.0
.
(Note: this question only asks you to move the ball from left to right, and not necessarily back from right to left.)
To make the ball move to the right with a velocity of 1, we can use the following rules:
Vert. Rule: return 0;
Horiz. Rule: return pos + 1;
This says that the new horizontal position will be 1 more than the current horizontal position -- i.e., the ball will move to the right 1 step every time the horizontal rule is called. (Note that the Spirograph program takes care of periodically calling the rules -- you don't have to do that yourself.) To make the ball move faster, we simply increase the amount we add to pos. (Remember that velocity is the rate of change of position.)
A slightly redundant, but sometimes more readable, way of writing this rule is as follows:
double velocity = 5; //
change this number to change the velocity
double newPos; //
the new position will be stored in newPos
newPos = pos + velocity; // compute next position
return newPos;
(Note that the name velocity here is a new local variable we
create, and is not the same as vel, which is a parameter
supplied to the rule.)
The answer to this depends on your implementation. With the code above, moving the ball to a different position causes the ball to continue moving with the same velocity, but starting from the position you moved it to. This is because the new position is computed relative to the current position, so it doesn't matter what the current position is.
Just as velocity is the rate of change in position, acceleration is the rate of change in velocity. Thus, to implement acceleration, we can start with the code for velocity above, and then just increment velocity each time the rule is called. That is, the rule will now be:
double velocity = 5;
// change this number to set the velocity
double acceleration = 1; // change this number
to set acceleration
double newPos; // the new position will be stored in newPos
newPos = pos + velocity; //
compute next position
velocity = velocity + acceleration;
return newPos;
However, if you run this code as-is, you will find that the velocity will not change. This is because right now, a new "shoebox" with the name velocity is created everytime the rule is called, and it loses its value after the rule returns. To make velocity keep its value across calls to the rule, we must make it a field. Thus, the correct(ed) code for acceleration is as follows:
In the fields box:
// Press "Load" to initialize these fields
double velocity = 5; // change this
to set *initial* velocity
double acceleration = 1; // change this to
set acceleration
In the rule box:
double newPos; // the new position will be stored in newPos
newPos = pos + velocity; //
compute next position
velocity = velocity + acceleration; //
compute next velocity
return newPos;
Note that we don't really need to give the acceleration a name, since it is constant. If we knew we would only be interested in doing accelerations of value 1, then we can just say velocity = velocity + 1; instead. However, using a name (acceleration) makes the code much more readable. It also makes it more flexible. If we wanted to change the acceleration (and/or the velocity) during run-time, we only need to assign a new value to the fields acceleration and velocity; we don't need to recompile our code.
Note that unlike velocity and acceleration, newPos is still a local
variable. This is because newPos is essentially used only for temporary
storage -- it is assigned a completely new value every time the rule is
called, and there is no need or reason for us to keep its old value around.
Thus, although making newPos into a field will not change the behavior
of this code, it is more appropriate to keep it as a local variable.
Can you make the dot go in a parabolic path? (Hint: what accelerations does it need?)
One way to do this is to use a constant horizontal velocity, a constant vertical acceleration, and an initial vertical velocity in the opposite directions as the vertical acceleration. (Note that this is what happens when you shoot a cannonball into the air.)
To do this, use the acceleration code above, with the different initial values for the fields:
Horiz. fields: double velocity = 5;
double acceleration = 0;
Vert. fields: double velocity
= 15;
double acceleration = -1;
(Note: In Spirograph, you need to press "Load" to initialize the fields.)
double newPos = pos + velocity;
// compute next position
velocity = velocity + acceleration; // compute
next velocity
if (newPos > maxPos) { //
if new position is too high
newPos = -maxPos; //
wrap-around to low end
} else if (newPos < -maxPos) { //
if new position is too low
newPos = maxPos;
// wrap-around to high end
}
// at this point, newPos can never be > maxPos
or < maxPos
// therefore, it is now safe to return newPos;
return newPos;
(This solution assumes that velocity and acceleration
are still fields.)
One way to do it is as follows:
double newPos = pos + velocity;
// compute next position
velocity = velocity + acceleration; // compute
next velocity
if (newPos > maxPos) { //
if new position is too high
newPos = maxPos; //
stay at maxPos
velocity = -velocity; //
but turn around (negate velocity)
} else if (newPos < -maxPos) { //
if new position is too low
newPos = -maxPos;
// stay at -maxPos
velocity = -velocity; //
but turn around (negate velocity)
}
// at this point, newPos can never be > maxPos
or < maxPos
// therefore, it is now safe to return newPos;
return newPos;
Again, this assumes velocity and acceleration fields. There is no way to make the ball bounce without using some field, but there are many different ways to use a field to accomplish bouncing.
Horiz. Rule:
return pos + 1; //
just move horizontally at constant vel.
Vert. Rule:
// move y position to
x*x (whatever the current x position is)
return (otherPos*otherPos);
To do the other functions, just replace the last line with:
return Math.sin( otherPos );
// this calls the Math.sin
// library method.
or,
return (1/otherPos);
By default, the ball will start at (0,0) and then start plotting on the right half of the screen. To make it plot the left half too, you can either manually move the ball to the left half with the mouse, or you can modify the wrap-around code above so that the ball will go to the left half when it reaches the right edge of the screen.
You may notice that the plots do not look very interesting. This is because of the scale of the plot. For example, the magnitude of sin( x ) is always <= 1, so the plot looks almost like a flat line. You can fix this problem by scaling the position values appropriately. For example:
Vert. Rule:
double scaledOtherPos; //
scaled version of otherPos
double newPos;
// holds computed position
double scaledNewPos;
// scaled version of newPos
// divide otherPos by
50 to "stretch" out Horiz. axis.
// (e.g., if the range
of the screen is -200 to +200, then
// we make it effectively
only -4 to + 4)
scaledOtherPos = otherPos / 50;
// compute function
newPos = Math.sin( scaledOtherPos );
// "magnify" the newPos
scaledNewPos = newPos * 50;
return scaledNewPos;
(Don't worry if you don't understand scaling at this point. You
are not required to. If you're interested in this sort of stuff,
however, don't hesitate to talk to the staff about it.)
You can do this by giving the ball the appropriate accelerations, and initial velocity, as we did above (in position control mode). For example, in acceleration mode, we might say:
Horiz Rule.: return 0; Vert. Rule: return - 5;
And then, you can use the Advanced Environment Options to set its velocity to 5 and 15, for x and y respectively.
Challenge: Write code that will draw a circle.
(Note: this is presented here only for those interested in it. It is relatively challenging material, even for experienced programmers, and deals more with Physics and Math than with programming. You are not required to understand this for 6.096.)
One way to draw a circle in acceleration-control mode is by using the centripetal force equation a=v^2/r. If you use the following code as both rules, and give the ball an appropriate initial position (e.g., use the mouse to move it to (100,0) ), and initial velocity (e.g., use Advanced Environment Options to set the velocity to (0,8)), it should plot a circle:
// compute radius magnitude
double r = Math.sqrt( pos*pos + otherPos*otherPos );
// compute velocity magnitude
double v = Math.sqrt( vel*vel + otherVel*otherVel );
// compute projection angle "theta" for this
dimension
double th = Math.atan2( otherPos, pos );
// compute acceleration component for this
dimension
double a = (-( v * v / r ) * Math.cos( th ));
// return acceleration
return a;
Explaining why these equations work is beyond the scope of this solution
set, but if you're interested in this sort of stuff, feel free to talk
to us about it.
This course is a part of Lynn Andrea Stein's Rethinking CS101 project at the MIT AI Lab and the Department of Electrical Engineering and Computer Science at the Massachusetts Institute of Technology.