Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I know what coupling and cohesion mean.
I have got the following example and it has some maintainability issues and therefore it needs some refactoring:
The problem is, I could not relate any coupling, cohesion or any other maintainability issue other than GLOBAL VARIABLES. How can I refactor the following code without this global variables issue (because global variables increase complexity & increases the code inflexibility?!)
double value;
double min, max;
public void read()
{
do
{
value = ConsoleInput.readDouble();
}
while(value < min || value > max);
}
public double hyp()
{
double x, y;
min = 0.0;
max = 100.0;
read();
x = value;
read();
y = value;
return Math.sqrt(x * x + y * y);
}
I was thinking it to refactor like below:
public void read()
{
double value;
double min = 0.0;
double max = 100.0;
do
{
value = ConsoleInput.readDouble();
}
while(value < min || value > max);
}
public double hyp()
{
double x, y;
read();
x = value;
read();
y = value;
return Math.sqrt(x * x + y * y);
}
Does this look right? Or is there any other efficient way of refactoring this?
Refactor your read() method like this:
public double read(double min, double max)
So rather than saving the value in a global, you return it from the function
Having "global variables" like min and max is absolutely fine, if they are "global" only inside its own class - thats the way the class variables are supposed to be used.
However "read" value should return value, not insert it into some class variable and then use. Also it would be nice to create instance of class with min and max in constructor for maximum flexibility, but also having default constructor.
public class GoodApp {
private double min, max;
public GoodApp(double min, double max){
this.min = min;
this.max = max;
}
public GoodApp(){
this(1,100);
}
public double read() {
double value;
do {
value = ConsoleInput.readDouble();
} while (value < min || value > max);
return value;
}
public double hyp() {
double x, y;
x = read();
y = read();
return Math.sqrt(x * x + y * y);
}
}
Based on the information you provided, I would suggest the following:
public double read() {
// set value to a not accepted value to start the while-loop
double value = -1;
double min = 0.0;
double max = 100.0;
while(value < min || value > max) {
value = ConsoleInput.readDouble();
}
return value;
}
public double hyp() {
double x = read();
double y = read();
return Math.sqrt(x * x + y * y);
}
Here is my version.
Few points to keep in mind - A method should expose its dependencies properly (What it depends on - like dependency injection), otherwise it can be a liar.
Also, your read method is not making use of the state of current object (i.e. it is not employing this reference). So, it can be static (but that makes unit testing tough - if it is a concern for you).
So, I would suggest the following (This may seem to be overkill for this small program - but good in real time projects. It reduces coupling because you can push any implementation of ReadData) -
enum Bound{
MAX(100.0), MIN(0.0);
public double value(){
return this.value;
}
private final double value;
private Bound(double value){
this.value = value;
}
}
public class CalcHyp{
ReadData readData;
CalcHyp(ReadData readData){
this.readData = readData;
}
public double hyp() {
double x = readData.read();
double y = readData.read();
return Math.sqrt(x * x + y * y);
}
public static void main(String[] args) {
CalcHyp calcHyp = new CalcHyp(new ReadData());//Declare the dependencies.(Dependency Injection)
System.out.println(calcHyp.hyp());
}
}
class ReadData{ //Can declare an interface in real time, and various implementations based on your requirement.
double read() {
double value = Bound.MAX.value()+1;
while(value < Bound.MIN.value() || value > Bound.MAX.value()) {
value = ConsoleInput.readDouble();
}
return value;
}
}
Related
I've been trying to write a simple function in Java that can calculate a number to the nth power without using loops.
I then found the Math.pow(a, b) class... or method still can't distinguish the two am not so good with theory. So i wrote this..
public static void main(String[] args) {
int a = 2;
int b = 31;
System.out.println(Math.pow(a, b));
}
Then i wanted to make my own Math.pow without using loops i wanted it to look more simple than loops, like using some type of Repeat I made a lot of research till i came across the commons-lang3 package i tried using StringUtils.repeat
So far I think this is the Syntax:-
public static String repeat(String str, int repeat)
StringUtils.repeat("ab", 2);
The problem i've been facing the past 24hrs or more is that StringUtils.repeat(String str, int 2); repeats strings not out puts or numbers or calculations.
Is there anything i can do to overcome this or is there any other better approach to creating a function that calculates powers?
without using loops or Math.pow
This might be funny but it took me while to figure out that StringUtils.repeat only repeats strings this is how i tried to overcome it. incase it helps
public static int repeat(int cal, int repeat){
cal = 2+2;
int result = StringUtils.repeat(cal,2);
return result;
}
can i not use recursion maybe some thing like this
public static RepeatThis(String a)
{
System.out.println(a);
RepeatThis(a);
}
just trying to understand java in dept thanks for all your comments even if there were syntax errors as long as the logic was understood that was good for me :)
Another implementation with O(Log(n)) complexity
public static long pow(long base, long exp){
if(exp ==0){
return 1;
}
if(exp ==1){
return base;
}
if(exp % 2 == 0){
long half = pow(base, exp/2);
return half * half;
}else{
long half = pow(base, (exp -1)/2);
return base * half * half;
}
}
Try with recursion:
int pow(int base, int power){
if(power == 0) return 1;
return base * pow(base, --power);
}
Function to handle +/- exponents with O(log(n)) complexity.
double power(double x, int n){
if(n==0)
return 1;
if(n<0){
x = 1.0/x;
n = -n;
}
double ret = power(x,n/2);
ret = ret * ret;
if(n%2!=0)
ret = ret * x;
return ret;
}
This one handles negative exponential:
public static double pow(double base, int e) {
int inc;
if(e <= 0) {
base = 1.0 / base;
inc = 1;
}
else {
inc = -1;
}
return doPow(base, e, inc);
}
private static double doPow(double base, int e, int inc) {
if(e == 0) {
return 1;
}
return base * doPow(base, e + inc, inc);
}
I think in Production recursion just does not provide high end performance.
double power(double num, int exponent)
{
double value=1;
int Originalexpn=exponent;
double OriginalNumber=num;
if(exponent==0)
return value;
if(exponent<0)
{
num=1/num;
exponent=abs(exponent);
}
while(exponent>0)
{
value*=num;
--exponent;
}
cout << OriginalNumber << " Raised to " << Originalexpn << " is " << value << endl;
return value;
}
Use this code.
public int mypow(int a, int e){
if(e == 1) return a;
return a * mypow(a,e-1);
}
Sure, create your own recursive function:
public static int repeat(int base, int exp) {
if (exp == 1) {
return base;
}
return base * repeat(base, exp - 1);
}
Math.pow(a, b)
Math is the class, pow is the method, a and b are the parameters.
Here is a O(log(n)) code that calculates the power of a number. Algorithmic technique used is divide and conquer. It also accepts negative powers i.e., x^(-y)
import java.util.Scanner;
public class PowerOfANumber{
public static void main(String args[]){
float result=0, base;
int power;
PowerOfANumber calcPower = new PowerOfANumber();
/* Get the user input for the base and power */
Scanner input = new Scanner(System.in);
System.out.println("Enter the base");
base=input.nextFloat();
System.out.println("Enter the power");
power=input.nextInt();
result = calcPower.calculatePower(base,power);
System.out.println(base + "^" + power + " is " +result);
}
private float calculatePower(float x, int y){
float temporary;
/* Termination condition for recursion */
if(y==0)
return 1;
temporary=calculatePower(x,y/2);
/* Check if the power is even */
if(y%2==0)
return (temporary * temporary);
else{
if(y>0)
return (x * temporary * temporary);
else
return (temporary*temporary)/x;
}
}
}
Remembering the definition of the logarithm, this can be done with ln and exp if these functions are allowed. Works for any positive base and any real exponent (not necessarily integer):
x = 6.7^4.4
ln(x) = 4.4 * ln(6.7) = about 8.36
x = exp(8.36) = about 4312.5
You can read more here and also here. Java provides both ln and exp.
A recursive method would be the easiest for this :
int power(int base, int exp) {
if (exp != 1) {
return (base * power(base, exp - 1));
} else {
return base;
}
}
where base is the number and exp is the exponenet
This question already has answers here:
Calculate the power of any exponent (negative or positive)
(5 answers)
Closed 9 years ago.
I need to write a method named pow2 that accepts a real number base and an integer exponent as parameters. It should return the base raised to the given power. Your code should work for both positive and negative exponents. For example, the call pow2(2.0, -2) returns 0.25. Do not use Math.pow in your solution.
This is what I have so far:
public double pow2(double x,int y){
double total=1;
for(int i=1;i<=y;i++){
total*=x;
}
return total;
}
But the problem is when I try to call pow(2.0, -2), it returns me 1.0 instead. How do I implement this method?
You have to branch, depending if you have a negative or a positive value.
Here a version that works with recursion:
public double pow2(double x,int y){
return _pow2(1.0, x, y);
}
private double _pow2(double res, double x, int y) {
if (y < 0) return _pow2(res/x, x, y+1);
if (y > 0) return _pow2(res*x, x, y-1);
return res;
}
If y is too big or too small, then you'll run into a stack overflow, so changing it to a non-recursive function is left to the op.
Edit: about your last question, you set the result to 1.0, the body of the loop is never used because !(1 <= -2), so you return the unmodified result of 1.0
Well, finally if you want to do it in an iterative way, just check first if y is positive or negative.
public double pow2(double x, int y)
{
double total = 1.0;
if(y > 0)
{
for(int i = 1 ; i <= y ; i++)
{
total *= x;
}
}
else
{
for(int i = -1 ; i >= y ; i--)
{
total /= x;
}
}
return total;
}
public static void main(String[] args) {
System.out.println(pow2(2,3));
}
public static double pow2(double x,int y){
double total=1;
for(int i=1;i<=y;i++){
total*=x;
}
return total ;
}
public static double pow2(double x,int y){
double total=1;
if(y>0){
for(int i=1;i<=y;i++){
total*=x;
}
return total;
}
else if (y<0){
double temp=1/x;//this makes 2 as 1/2
y=y*-1; //to have a meaningful iteration if for loop
for(int i=1;i<=y;i++){
total*=temp;
}
return total;
}else
return 1;
}
I am trying to convert a C code to java, it's the Newton Raphson algorithm implementation. All is going well but there is a problem of pointers which were used in C code and i have removed them in java. The C code part is:
x = newton(x_0, error, max_iters, &iters, &converged); //Call to a function (newton)
if (converged) {
printf("Newton algorithm converged after %d steps.\n", iters);
printf("The approximate solution is %19.16e\n", x);
printf("f(%19.16e) = %19.16e\n", x, f(x));
} else
{
printf("Newton algorithm didn't converge after %d steps.\n",
iters);
printf("The final estimate was %19.16e\n", x);
printf("f(%19.16e) = %19.16e\n", x, f(x));
}
and the function definition is something like this:
double newton(double x_0, double error, int max_iters,
int* iters_p, int* converged_p)
Now the problem is that, the values of two pointer variables are just zero every time. Also the if(converged) shows an error message of incomoatible types. required boolean, found int. Below is the java code so please help overcome this.
//Member Functions///////
public
double function( double x)
{
return x*x - 2;
}
double F_Deriv( double x )
{
return 2.0*x;
}
double newton(double x_0, double error, int max_iters,int iters, int converged)
{
double x = x_0;
double x_prev;
int iter = 0;
do {
iter++;
x_prev = x;
x = x_prev - function(x_prev)/F_Deriv(x_prev);
}
while (Math.abs(x - x_prev) > error && iter < max_iters);
if (Math.abs(x - x_prev) <= error)
converged = 1;
else
converged = 0;
iters = iter;
return x;
}
/////Main Function///////
public static void main(String[] args) {
Newton_Raphson obj=new Newton_Raphson();
Scanner input=new Scanner(System.in);
double x_0; /* Initial guess */
double x; /* Approximate solution */
double error; /* Maximum error */
int max_iters; /* Maximum number of iterations */
int iters; /* Actual number of iterations */
int converged; /* Whether iteration converged */
System.out.println( "Enter Initial Solution: " );
x_0=input.nextDouble();
System.out.println( "Enter Error: " );
error=input.nextDouble();
System.out.println( "Enter Maximum Iterations: " );
max_iters=input.nextInt();
x = obj.newton(x_0, error, max_iters, iters, converged);
if(converged)
{
System.out.println("Newton algorithm converged after "+ iters +" steps.");
System.out.println("The approximate solution is "+ x);
}
else
{
System.out.println("Newton algorithm didn't converge after " + iters + " steps.");
System.out.println("The final estimate was " + x);
}
}
Java passes arguments by value, so
if (Math.abs(x - x_prev) <= error)
converged = 1;
else
converged = 0;
iters = iter;
doesn't change the passed arguments for the caller. These changes never leave the called function.
The simplest way to mimick out-parameters, resp. passed pointers in C, is to pass a one-length array,
double newton(double x_0, double error, int[] max_iters,int iters, boolean[] converged)
and set (and query) iters[0] resp. converged[0].
One problem is that this statement:
if (Math.abs(x - x_prev) <= error)
converged = 1;
else
converged = 0;
is not doing anything because Java is pass by value. So it won't affect the value of converged outside the method. You could instead return an object from your method which would contain 2 members: x and converged:
return new NewtonResult (x, iters, converged);
with NewtonResult defined as:
public class NewtonResult {
int x;
int iters;
boolean converged;
NewtonResult (int x, int iters, boolean converged) {
this.x = x;
this.iters = iters;
this.converged = converged;
}
}
Another problem in your code is that Java if requires a boolean when you are passing an int, so you need to change your condition to:
if (converged != 0) {
//
}
or even better make converged be a boolean.
The problem is that converged and iters are returned from the original C code. The use of pointers for those parameters is so that the parameters can mimic out semantics. Since Java only supports pass by value, you cannot return that information in the same way using plain method parameters.
The other issue is that older versions of C do not have a boolean type and so int is used instead. The flag to indicate convergence should be a boolean in Java.
So your code needs to return three pieces of information: the result (a floating point value), converged (a boolean value) and iters (an integer). You should wrap these up into an object and return them that way.
The class you need would look like this:
public class NewtonResult {
public boolean converged;
public double value;
public int iters;
}
You should change your newton method signature to be like so:
NewtonResult newton(double x_0, double error, int max_iters)
Finally, I think that tolerance would be a much better name than error for that parameter.
The class declaration is missing (public class Newton_Raphson...).
As said above, Java does not support arguments passed by reference, only by value, so you will need to wrap all those in a "Result" class.
public class Result {
public int x;
public int iters;
public int converged; // better replace this with a boolean in Java
}
and change the return type of your method to that Result class.
You cannot test an int as a boolean. You should test that it is different from 0 (since in C everything different than 0 is considered as true). Or consider using a boolean directly, it's much easier.
When passing premitive types such as int, boolean- in java as method parameters and changing them, in reality they will not be changed.
The parmeters passed are the copy of the real ones (they are actually being passed by value).
Initialize objects out of the varaiables and then pass them to the methods as:
Integer[] a = new Integer[1]; // For int a
Boolean[] b = new Boolean[1]; // For boolean b
a[0] = 1;
b[0] = true;
This way the copy of the reference of the passed object will be passed, and when you change the value of one of its elements like [0] above, it will be also changed in the real variable.
I'm having difficulty writing a program to solve this exercise from a Java text book:
Write a method raiseRealToPower that takes a floating-point value x and an integer
k and returns xk. Implement your method so that it can correctly calculate the result
when k is negative, using the relationship
x^(-k) = 1 / x^k.
Use your method to display a table of values of πk for all values of k from –4 to 4.
I didn't done this part with PI, i know that, if my programs starts to work... this is what i done... tell me please, what is wrong.
import acm.program.*;
public class vjezba55 extends ConsoleProgram {
private static final double PI = 3.14159253;
public void run() {
double x = readDouble ("x: ");
double k = readDouble ("k: ");
println ("x^k = " + raiseDoublePower(x,k));
}
/* Method that counts x^k */
private double raiseDoublePower (double x, double k){
if (k >= 0) {
return Math.pow(x, k);
}
else {
double total = 1;
for (int i= 0; i>k; i--) {
total = (double) 1 / x;
}
return total;
}
}
}
Take a look at your loop code. You are just recalculating total from scratch on each iteration, rather than updating the previous result.
I don't understand the part in the question regarding PI, but your method may be much simpler (according to using the relationship x^(-k) = 1 / x^k):
private double raiseDoublePower (double x, double k){
if (k >= 0) {
return Math.pow(x, k);
}
else {
return 1 / Math.pow(x, -k);
}
}
Say I have the following three constants:
final static int MY_INT1 = 25;
final static int MY_INT2 = -10;
final static double MY_DOUBLE1 = 15.5;
I want to take the three of them and use Math.max() to find the max of the three but if I pass in more then two values then it gives me an error. For instance:
// this gives me an error
double maxOfNums = Math.max(MY_INT1, MY_INT2, MY_DOUBLE2);
Please let me know what I'm doing wrong.
Math.max only takes two arguments. If you want the maximum of three, use Math.max(MY_INT1, Math.max(MY_INT2, MY_DOUBLE2)).
you can use this:
Collections.max(Arrays.asList(1,2,3,4));
or create a function
public static int max(Integer... vals) {
return Collections.max(Arrays.asList(vals));
}
If possible, use NumberUtils in Apache Commons Lang - plenty of great utilities there.
https://commons.apache.org/proper/commons-lang/javadocs/api-3.1/org/apache/commons/lang3/math/NumberUtils.html#max(int[])
NumberUtils.max(int[])
Math.max only takes two arguments, no more and no less.
Another different solution to the already posted answers would be using DoubleStream.of:
double max = DoubleStream.of(firstValue, secondValue, thirdValue)
.max()
.getAsDouble();
Without using third party libraries, calling the same method more than once or creating an array, you can find the maximum of an arbitrary number of doubles like so
public static double max(double... n) {
int i = 0;
double max = n[i];
while (++i < n.length)
if (n[i] > max)
max = n[i];
return max;
}
In your example, max could be used like this
final static int MY_INT1 = 25;
final static int MY_INT2 = -10;
final static double MY_DOUBLE1 = 15.5;
public static void main(String[] args) {
double maxOfNums = max(MY_INT1, MY_INT2, MY_DOUBLE1);
}
Java 8 way. Works for multiple parameters:
Stream.of(first, second, third).max(Integer::compareTo).get()
I have a very simple idea:
int smallest = Math.min(a, Math.min(b, Math.min(c, d)));
Of course, if you have 1000 numbers, it's unusable, but if you have 3 or 4 numbers, its easy and fast.
Regards,
Norbert
Like mentioned before, Math.max() only takes two arguments. It's not exactly compatible with your current syntax but you could try Collections.max().
If you don't like that you can always create your own method for it...
public class test {
final static int MY_INT1 = 25;
final static int MY_INT2 = -10;
final static double MY_DOUBLE1 = 15.5;
public static void main(String args[]) {
double maxOfNums = multiMax(MY_INT1, MY_INT2, MY_DOUBLE1);
}
public static Object multiMax(Object... values) {
Object returnValue = null;
for (Object value : values)
returnValue = (returnValue != null) ? ((((value instanceof Integer) ? (Integer) value
: (value instanceof Double) ? (Double) value
: (Float) value) > ((returnValue instanceof Integer) ? (Integer) returnValue
: (returnValue instanceof Double) ? (Double) returnValue
: (Float) returnValue)) ? value : returnValue)
: value;
return returnValue;
}
}
This will take any number of mixed numeric arguments (Integer, Double and Float) but the return value is an Object so you would have to cast it to Integer, Double or Float.
It might also be throwing an error since there is no such thing as "MY_DOUBLE2".
int first = 3;
int mid = 4;
int last = 6;
//checks for the largest number using the Math.max(a,b) method
//for the second argument (b) you just use the same method to check which //value is greater between the second and the third
int largest = Math.max(first, Math.max(last, mid));
You can do like this:
public static void main(String[] args) {
int x=2 , y=7, z=14;
int max1= Math.max(x,y);
System.out.println("Max value is: "+ Math.max(max1, z));
}
if you want to do a simple, it will be like this
// Fig. 6.3: MaximumFinder.java
// Programmer-declared method maximum with three double parameters.
import java.util.Scanner;
public class MaximumFinder
{
// obtain three floating-point values and locate the maximum value
public static void main(String[] args)
{
// create Scanner for input from command window
Scanner input = new Scanner(System.in);
// prompt for and input three floating-point values
System.out.print(
"Enter three floating-point values separated by spaces: ");
double number1 = input.nextDouble(); // read first double
double number2 = input.nextDouble(); // read second double
double number3 = input.nextDouble(); // read third double
// determine the maximum value
double result = maximum(number1, number2, number3);
// display maximum value
System.out.println("Maximum is: " + result);
}
// returns the maximum of its three double parameters
public static double maximum(double x, double y, double z)
{
double maximumValue = x; // assume x is the largest to start
// determine whether y is greater than maximumValue
if (y > maximumValue)
maximumValue = y;
// determine whether z is greater than maximumValue
if (z > maximumValue)
maximumValue = z;
return maximumValue;
}
} // end class MaximumFinder
and the output will be something like this
Enter three floating-point values separated by spaces: 9.35 2.74 5.1
Maximum is: 9.35
References Java™ How To Program (Early Objects), Tenth Edition
Simple way without methods
int x = 1, y = 2, z = 3;
int biggest = x;
if (y > biggest) {
biggest = y;
}
if (z > biggest) {
biggest = z;
}
System.out.println(biggest);
// System.out.println(Math.max(Math.max(x,y),z));