I'm trying to check if a number is a square, and if a number is triangular.
The issue is happening at sqrt(num) which is returning 0 for all numbers I test.
I'm using an online compiler, tried several compilers, so it's not a compiling issue. Tried to declare num as a double and as an int, same results.
I'm new to Java, but not new to programming, I searched online, checked my code several times, everything looks fine, it even worked as expected before adding the variables for checking triangular number, but after declaring the variables checkTri and checkTriSqr, this started to happen. I'm sure this have nothing to do with declaring these variables (almost sure), could anyone please help me understand what's going on here?
import static java.lang.Math.sqrt;
import static java.lang.Math.round;
public class Parent{
public static void main(String[] args){
class Number
{
public int num ;
double numSqr = sqrt(num );
double roundNumSqr = round(numSqr) ;
double checkTri = 8 * num + 1 ;
double checkTriSqr = sqrt(checkTri) ;
public void prinTest()
{
System.out.println(num);
System.out.println(numSqr);
System.out.println(roundNumSqr);
System.out.println(checkTri);
System.out.println(checkTriSqr);
}
public boolean isSqr()
{
if (numSqr == roundNumSqr)
{
return true;
}
else
{
return false;
}
}
public boolean isTriangular(){
if (checkTriSqr * checkTriSqr == checkTri )
{
return true;
}
else
{
return false;
}
}
}
Number number = new Number();
number.num = 350;
number.prinTest();
System.out.println(number.isSqr());
System.out.println(number.isTriangular());
}
}
EDIT: The following screen shot is from the tutorial I'm following, concerning declaring classes within methods!
This:
public int num ;
double numSqr = sqrt(num );
initialises num to 0 upon instance construction (the default value for an integer in the absence of assignment), and numSqr is set immediately afterwards (to zero).
You need to recalculate the sqrt() each time you subsequntly set num (perhaps by providing a method setNum() and recalculating everything within that method)
I wouldn't call your class Number, btw. There's already a Number class in the standard Java class set.
numSqr is created in the constructor, whereas number.num = 350;is declared after the construction of your object.
You can use a constructor like this :
public Numer(int num){
this.num=num;
this.numSqr=sqrt(num)
//.... ... ...
}
You can also use an empty constructor and a setter to set the number attribute :
public void setNumber(int num){
this.num=num;
this.numSqr=sqrt(num)
//.... ... ...
}
The values numSqr, roundNumSqr, etc, are all set at the point of the object's creation, however you don't set num to anything until after the object is created. The result is that, for instance,
At creation:
num = 0
therefore
numSqr = 0
roundNumSqr = 0
etc
Then, you set num = 350
But you don't reset the values of numSqr, etc, so this is still the case:
numSqr = 0
roundNumSqr = 0
You need to make a constructor for this class that takes in the value of num and then sets all of the corresponding values, so that they're only set after num has been set (or, add a "calculate" function that updates all the values).
You can modify in this way and compare with technology you have worked on .
import static java.lang.Math.sqrt;
import static java.lang.Math.round;
public class Number {
public int num = 0;
public void prinTest() {
System.out.println(this.num);
System.out.println(this.getSqrt(this.num));
System.out.println(this.getCheckTri());
}
private double getSqrt(double value) {
return sqrt(value);
}
public boolean isSqr() {
if (this.getSqrt(this.num) == round(this.getSqrt(this.num))) {
return true;
} else {
return false;
}
}
private double getCheckTri() {
return 8 * this.num + 1;
}
public boolean isTriangular() {
if (this.getSqrt(this.getCheckTri()) * this.getSqrt(this.getCheckTri()) == this.getCheckTri()) {
return true;
} else {
return false;
}
}
public static void main(String[] args) {
Number number = new Number();
number.num = 49;
number.prinTest();
System.out.println(number.isSqr());
System.out.println(number.isTriangular());
}
}
You should read some basic tutorials as you have added class inside main method,which means you need more time to check out the syntax.
The other answers alreade said, that the field num was not set to the input number, and that the other fields were actually evaluated on object creation, and hence zero too.
The purpose however is achieved by simple functions:
public static boolean isSquare(int num) {
int root = (int) Math.round(Math.sqrt(num));
return root*root == num;
}
public static boolean isCubic(int num) {
int root = (int) Math.round(Math.cbrt(num));
return root*root*root == num;
}
This exploits the cubic root.
As a comparison of doubles, a sqrt result and its rounded long value are still imprecise, I prefer to recalculate the original parameter.
public int num ;
double numSqr = sqrt(num);
By default, declared instance integer variables (variables declared inside class body) are initialized with 0 (zero). Hence, your code does nothing but take a square root of zero, which is zero.
Related
I'm working on a calculator and I search how I can optimize my code.
The thing is that I have much code duplication due to if I'm working on the first number of the calculation or the second. So I'm searching if it is possible to modify the value of an attribute sent in argument of a function ? (I think not because I saw nowhere the answer).
Maybe I'm expressing myself badly so here is a code below to explain what I'm talking about:
public class MyClass
{
private static int number1 = 1;
private static int number2 = 2;
public MyClass()
{
changeValueOf(number1, 3);
}
private static void changeValueOf(int number, int value)
{
//Change here the value of the correct field
}
}
First of all, you can modify static variables inside the method:
private static void changeValueOf(int value)
{
number1 = value;
}
But I guess that is not what you a looking for :)
In Java (and in most other languages) primitive data type (int, short, long, etc) passed by value, e.g. the copy of value passes to the method (function).
And reference types (objects, e.g. created with new operator) passed by reference. So, when you modigy the value of reference type (object) you can see the changes in the outer scopes (for example, in method caller).
So, the answer is no - you cannot change the value of int so that the outer scope would see the updated value.
Howewer, you could wrap your int values with some object - and it change the value inside of it:
public class Example {
public static void main(String[] args) {
Example app = new Example();
// Could be static as well
Holder val1 = new Holder(1);
Holder val2 = new Holder(2);
app.changeValue(val1, 7);
System.out.println(val1.value); // 7
}
public void changeValue(Holder holder, int newValue) {
holder.value = newValue;
}
static class Holder {
int value;
Holder(int value) {
this.value = value;
}
}
}
Also, you could create an array with 2 values and update them inside the method, but it's not very good approach IMO
And finally, you could just return updated value and assign it to your variables:
public class Example {
private static int number1 = 2;
private static int number2 = 3;
public static void main(String[] args) {
Example app = new Example();
number1 = app.mul(number1, 7);
number2 = app.mul(number2, 7);
System.out.println(number1); // 14
System.out.println(number2); // 21
}
public int mul(int a, int b) {
return a * b;
}
}
One possibility is to use an array to store your variables, instead of separate variables with numbers affixed. Then you would write number[1] instead of number1 for example. You can pass the array index number around to indicate which variable you are referring to.
public class MyClass
{
private static int[] variables = {1, 2};
public MyClass()
{
// change value of first variable
changeValueOf(0, 3);
// now variable[0] = 3
}
private static void changeValueOf(int number, int value)
{
variables[number] = value;
}
}
I have declared a default and a parameterize constructor. Using a single object I am calling both the constructor and an function. When I run the program I am getting the output as 0 instead of getting the factorial. I have initialize f=1 still the output is 0.
class Factorial
{
int num, f;
Factorial()
{
f = 1;
}
Factorial(int n)
{
num = n;
}
public int getFactorial()
{
for(int i = 1; i <= num; i++)
{
f = f * i;
}
System.out.println("Factorial= " + f);
return f;
}
public static void main(int m)
{
Factorial obj = new Factorial();
obj = new Factorial(m);
obj.getFactorial();
}
}
This is because the initial value of f remains zero when the class is initialized with the factorial(int n) constructor.
Set f to 1 in the initializer to fix this problem:
int n, f = 1;
Factorial() {
}
Factorial(int n) {
num = n;
}
This leaves your class with a big problem: calling getfactorial multiple times will change the state of the class, increasing the value of the factorial. You can fix this by creating a boolean variable that indicates whether the factorial has been computed or not, and returning f after the computation has been performed.
If you do not need "lazy" computation, make f a local variable in the method.
As a good practice, a variable should have the minimal possible scope (preferred local, then instance). Or in other words: state variables should be used just when you want to share some date between several methods of the same class. But what in your case? Factorial is an operation that may be computed in just one step, from one single parameter: No need to further processing.
So, I recommend you to refactorize your class to:
Drop off the state variables: Convert them to local variables or parameters to the method.
Set the factorial method as static (precisely because it does not need state variables).
Another small detail: Parameters are passed from command line to the main method through an array of Strings - always.
Leave all the inputs and outputs to/from the user in just one method, preferrably the main method.
So it will remain like this:
class Factorial
{
public static int getFactorial(int num)
{
int f=1;
for (int i = 1; i <= num; i++)
{
f = f * i;
}
return f;
}
public static void main(String[] args)
{
int m=Integer.parseInt(args[0]);
int factorial=Factorial.getFactorial(m);
System.out.printf("factorial of %d is %d\n", m, factorial);
}
}
Much simplier, isn't it?
I made a test program because I am trying to get back into Java after working in PL/SQL. I created a class Numbers that contains an integer, a getter and a setter. I have another class Test that is creating an instance of Numbers, and also adds that instance to a List. I created a for loop that loops two times and sets the value of the integer in Numbers equal to i. I then add that instance of Numbers to the List numbersList. I then do a print screen of the value that was added to the List. I do a total of 3 prints, one print the first time through the loop that prints the first position in the List, then I print two times during the second time through the loop,the first position in the List again, and the second position in the List. I was expecting to get 0,0,1 as the result. I am getting instead 0,1,1 as the result and I cannot figure out why. I am not changing anything in the first position in the List (numbersList[0]) during the second time through the loop, all I am doing is adding an instance of Numbers into the second position in the list (numbersList[1]).
import java.util.ArrayList;
import java.util.List;
public class Tests {
static int x;
public static void main(String[] args) {
List<Numbers> numbersList = new ArrayList<Numbers>();
Numbers numbers = new Numbers();
Numbers numbers2 = new Numbers();
for (int i = 0; i < 2; i++) {
if (i == 0) {
numbers.setVariable(i);
numbersList.add(numbers);
System.out.println(numbersList.get(0).getVariable());
}
if (i > 0) {
numbers2.setVariable(i);
numbersList.add(numbers2);
System.out.println(numbersList.get(0).getVariable());
System.out.println(numbersList.get(1).getVariable());
}
}
}
}
public class Numbers {
public static int a = 5;
public static void setVariable(int b) {
a = b;
}
public static int getVariable() {
return a;
}
}
public static int a = 5 means that all instances of Numbers share the same variable because of the static keyword.
Therefore, when you do numbers2.setVariable(i);, the variable is also changed for numbers. Hence the 0,1,1
If you want instance variables remove the static keywords from Numbers.
Your class Numbers has no instance fields (everything is static, or class level).
It should look something like (and overriding toString() is a good idea),
public class Numbers {
public int a = 5;
public void setVariable(int b){
a = b;
}
public int getVariable(){
return a;
}
#Override
public String toString() {
return String.valueOf(a);
}
}
By overriding toString() you can more easily print instances of Numbers. For example,
System.out.println(numbersList);
For an assignment we are suppose to modify a custom BitString class. There are over 10 functions we need to actually write the code for and I am stuck on the very first one. This is the beginning parts to the class along with some of the methods contained that I am trying to use:
public class BitString implements Cloneable {
// An array to hold the bits that make up the bit string.
private boolean bits[];
/**
* A constant that defines the size of the default bit string.
*/
public static final int DEFAULT_SIZE = 8;
/**
* Creates a new, all false, bit string of the given size.
*/
public BitString(int size) {
if (size < 1) throw new IllegalArgumentException("Size must be positive");
bits = new boolean[size];
}
/**
* Creates a new all false bit string of size DEFAULT_SIZE.
*/
public BitString() {
this(DEFAULT_SIZE);
}
/**
* Set the value of a bit string at the given index to true.
*/
public void set(int index) {
bits[index] = true;
}
/**
* Set the value of a bit string at the given index to false.
*/
public void clear(int index) {
bits[index] = false;
}
Below is the method I am working on (The only part that was given is the method and the input types) I can not call bits.set() or bits.clear() or the same operations that they are doing. When compiling I get
Error: Cannot make a static reference to the non-static field bits
on both method calls.
public static BitString decimalToUnsigned(int n, int size) {
//throw new UnsupportedOperationException("This function needs to be completed!");
int result = 0;
int multiplier = 1;
int base = 2;
while(n > 0) {
int remainder = n % base;
n = n / base;
if (remainder == 0) {
//value = false;
try {
//bits.clear(size);
bits[size] = false;
} catch (InsufficientNumberOfBitsException ie) {}
} else {
//value = true;
try {
//bits.set(size);
bits[size] = true;
} catch (InsufficientNumberOfBitsException ie) {}
}
result = result + remainder * multiplier;
multiplier = multiplier * 10;
size--;
}
System.out.println("Result..." + result);
return(bits);
}
Thanks for any help.
We're having to make some assumptions here: the static method is a method on BitString, for instance.
Given that, the method is evidently supposed to create a BitString object, since it returns one. So it should create one of the size you need for the parameters you are dealing with. Since you have the (arbitrary, somewhat silly) restriction of not being allowed to call the set and clear methods, you will need to access the bits variable from within the BitString that you create directly; since the static method is on the BitString class, you can do this:
public static BitString decimalToUnsigned(int n, int size)
{
// ...
BitString bitString = new BitString(size);
// ... loops, logic, etc. all to be put in here; when you're ready to
// access the bits array, use:
bitString.bits[index] = false;
// ...
// then when you're ready to return your BitString object, just:
return bitString;
}
Yes, bits is declared private, but that just means it cannot be accessed from outside the class. The static method is within the class, though it cannot use the member variables since the static method does not operate on an instance (other than one it creates).
See if that can get you through the compilation error and on to your logic.
p.s. I don't think this is a very good assignment; it will get your head around static vs. non-static methods, but I think there are better ways to do that. And saying that you have to use and return a class but you cannot call its methods is hardly a real-world scenario.
In your static method you need an instance of a BitString to put your vales in. This is how I would do it:
public class BitString implements Cloneable {
/** A constant that defines the size of the default bit string. */
public static final int DEFAULT_SIZE = 8;
// an array to hold the bits that make up the bit string
private boolean bits[];
/** Creates a new, all false, bit string of the given size. */
public BitString(int size) {
if (size < 1) {
throw new IllegalArgumentException("size must be positive");
}
bits = new boolean[size];
}
/** Creates a new all false bit string of size DEFAULT_SIZE. */
public BitString() {
this(DEFAULT_SIZE);
}
/** Set the value of a bit string at the given index to true. */
public void set(int index) { // might want to check index bounds
bits[index] = true;
}
/** Set the value of a bit string at the given index to false. */
public void clear(int index) { // might want to check index bounds
bits[index] = false;
}
public String toString() { // one possible implementation, might not want to add leading 0's
StringBuilder buf = new StringBuilder(bits.length);
for (Boolean bit : bits) {
buf.append(bit ? '1' : '0');
}
return buf.toString();
}
public static BitString decimalToUnsigned(int n, int size) {
// throw new UnsupportedOperationException("this function needs to be completed");
// might want to check that size is big enough
// this is the key here: you need an instance of the object that has the bits array inside it
BitString result = new BitString(size);
while (n != 0 && size > 0) {
size--; // use size to index into the BitString
if ((n & 1) == 1) { // % 2 doesn't work well with negative numbers, you have to worry about +-1 then
result.set(size); // set bit if needed
}
n = n >>> 1; // unsigned shift to the next bit
}
return result;
}
public static void main(String[] args) {
// can be invoked with just decimalToUnsigned(42, 10) but I want to make it more clear
BitString example1 = BitString.decimalToUnsigned(42, 10);
System.out.println(example1);
BitString example2 = BitString.decimalToUnsigned(-42, 10); // will treat -42 as unsigned
System.out.println(example2);
BitString example3 = BitString.decimalToUnsigned(-1, 33); // will treat -1 as unsigned giving 32 1's
System.out.println(example3);
}
}
It prints:
0000101010 1111010110 011111111111111111111111111111111
So, I'm very new to Java, I have a summer college course and we're on functions or methods and I'm having a bit of trouble understanding them.
There is a question on a lab I'm having a little trouble with:
"Write a method called MaxOfThree that accepts three integer
parameters and returns the largest of the three."
This is what I have so far but I'm not sure whats wrong. I added the print statement at the end because I wasn't getting a return value when I ran it but now I'm getting errors and it's not compiling. If you could help me understand methods a bit more I'd greatly appreciate it. For instance how the parameters work and calling it and if what's included in the function call is correct and how that works. I just get so confused when I read through the material and was hoping for an explanation in more layman's terms. Thanks for any help, here is what I have so far.
public class Test {
public static void main(String[] args) {
int a = 2, b = 3, c = 4;
int maxValue = max3(a, b, c);
}
public static int max3(int a, int b, int c) {
int max = a;
if (b > max) max = b;
if (c > max) max = c;
return max;
System.out.println(max);
}
}
Here are the errors I'm receiving just in case...
Test.java:16: error: unreachable statement
System.out.println(max);
^
Test.java:17: error: missing return statement
}
^
2 errors
You can't have a statement after the return statement, or to be more exact - a statement imediatelly after a return statement (such as your println) can never be executed, and is therefore an error.
The println should be before the return statement.
public static int max3(int a, int b, int c) {
int max = a;
if (b > max) max = b;
if (c > max) max = c;
System.out.println(max);
return max;
}
I suggest You to change those if statements into one simple for loop with simple int[] vector. This solution is much more elegant and flexible. Additionally, You initialized and not used anywhere int maxValue = max3(a, b, c); in Your code.
public class Demo {
public static void main(String args[]) {
int[] numbers = new int[] {2, 3, 4};
System.out.println(maxValue(numbers));
}
public static int maxValue(int[] n) {
int max = n[0];
for (int i = 1; i < n.length; i++) {
if (n[i] > max) {
max = n[i];
}
}
return max;
}
}
But let's bow for a moment on the problem of methods implementation in Java.
At the begining of Your journey through the vastness of the Java realm You should get familiar with two types of methods: 1) void methods, and 2) return methods. The first ones are responsible for doing something without returning any value. We can for example use them for setting values of the fields of our application, initializing GUI, or other operations. The use of the void method can look like this:
/* method declaration */
void setValue(int value) {
someField = value;
}
/* method invocation */
setValue(5);
After invocation of setValue(5) the value of the someField object will be 5. However, you have to remember about type compatibility, so in this case someField can not be e.g of String type.
Second method type mentioned above, i.e return method is very useful, when you expect the method to give You an output, e.g in result of some operations conducted on the data You've given to Your method. But of course it's not necessary, to provide for the return method an input. Anyway, the use of return method can look like this:
/* method returns text You've given to it */
String getText(String text) {
return text;
}
/* method returns result of addition of three given int's */
int calculate(int a, int b, int c) {
return a + b + c;
}
/* method return a random number */
int createRandomNumber() {
Random random = new Random();
return random.nextInt();
}
You can easily see, that there is plenty of space for improvisation. Basicaly and in summary, void methods can work with given objects, for example can set values and conduct other operations, but thay don't return any STRAIGHT results You can work with. Return methods, from the other hand, provide You physical results, which You can use in further operations, or even in other methods, for example:
import java.util.Random;
public class Demo {
private static int someValue;
public static void main(String args[]) {
setValue(calculate(
createRandomNumber(),
createRandomNumber(),
createRandomNumber()));
System.out.println(someValue);
}
public static void setValue(int value) {
someValue = value;
}
public static int calculate(int a, int b, int c) {
return a + b + c;
}
public static int createRandomNumber() {
Random random = new Random();
return random.nextInt();
}
}
The problem is that the compiler detects that execution will never reach the System.out.println line, so it refuses to compile. The line return max; effectively ends the method, so nothing more will run after that.
You should move return max; to below the System.out.println line.
Swap your last 2 lines (return and System).
It should be like this, return max statement should be the last line in your method if you want to print something, because return statement goes back or invoke the line that called him,so your print statement is not reach.
public static int max3(int a, int b, int c) {
int max = a;
if (b > max) max = b;
if (c > max) max = c;
System.out.println(max);
return max;
}
You need to put
System.out.println(max);
before:
return max;
the reason is your return unconditionally ends the function and therefore the compiler won't reach the println causing a compile error.
You have a System.out.println() statement after the return. return ends the method and so the System.out.println() will never happen because the method will have ended. That's why you are getting errors. Put the System.out.println() before the return:
public static int max3(int a, int b, int c) {
int max = a;
if (b > max) max = b;
if (c > max) max = c;
System.out.println(max);
return max;
}
As already been said, after you return something, the method will end. So your output in the last line of the method will not be executed, so remove it.
You can print the returned value of the method when you write the following outside of the method:
System.out.println("highest value:" + max3(a,b,c));
So now, the 3 values are given to the method which can do something with them now. After it did the calculations, the method returns a value, which can now be printed to the console for example.
The issue with the code you provided is that you're trying to print to the console, after you use your return statement. This causes your program to never reach that line: System.out.println(max);