I'm working on a project that involves using a system of equations to solve for certain radii. My method for that seems to be working fine, but to return the correct answer I need to return a ratio in the simpilest form. So 24/2 would come back as 12/1, which is stored in an array. So the final answer would be [12,1].
For numbers that work nicely I have no difficulty. But there are times when there will be radii that are 843.667 and I need to return this as the most basic fraction. And this is where I'm getting stumped because I cant figure out how to do it. Either I get a lossy conversion error, the wrong number, or just zeros.
//Class set-up to be given a double and return both its numerator and denominator
class Rational {
public int num, denom;
//Establishes both the numerator and denominator
public Rational(int num, int denom) {
this.num = num;
this.denom = denom;
}
public Rational(double d) {
//Split up the number, so that we have the integer value and decimal value
long i = (long) Math.ceil(d);
double numerator = d - i;
// Know how many decimal places we are dealing with and establish a proper numerator and denominator
String frac = new Double(numerator).toString();
frac = frac.substring(frac.indexOf('.'));
numerator = Double.parseDouble(frac);
int power = frac.length();
double denominator = Math.pow(10, power);
//Find the GCD of the numerator and denominator
double gcd = findGCD((int) numerator, (int) denominator);
numerator /= gcd;
denominator /= gcd;
this.num = (int) numerator;
this.denom = (int) denominator;
}
// Method to find the GCD of two int values
public static int findGCD(int n1, int n2) {
while (n1 != n2) {
if (n1 > n2) {
n1 = n1 - n2;
} else {
n2 = n2 - n1;
}
}
return n1;
}
}
If you can help figure out how my 843.667 could be turned into a fraction, that would be amazing.
Related
I have a class Calculator which aggregates instances of a class Fraction as its attributes.
Class Fraction has attributes num for numerator and denom for denominator.
Here is an abstract of the code with 'multiply' and 'simplify' (to get a fraction in its lowest terms) methods.
public class Calculator {
private Fraction f1 = new Fraction(4, 9);
private Fraction f2 = new Fraction(3, 8);
public void multiply() throws Exception {
int num = f1.getNum() * f2.getNum();
int denom = f1.getDenom() * f2.getDenom();
Fraction f = new Fraction(num, denom);
simplify(f);
System.out.print(f);
}
private void simplify(Fraction f) throws Exception {
int num = f.getNum();
int denom = f.getDenom();
for (int i = num; i > 0; i--) {
if ((num % i == 0) && (denom % i == 0)) {
num = num / i;
denom = denom / i;
break;
}
}
}
However, I get 12/72 as a result of multiplication while I should get 1/6.
How can I change the code so that 'simplify' method works when invoked in 'multiply'?
As Edwin commented you want algorithm for greatest common divisor. However to answer your question, you got unexpected result because the newly computed variables num and denom at the line with num = num / i are not stored back into Fraction f.
Either (worse option) call f.setNum(num); f.setDenom(denom) or (better) change Fraction to immutable class and return new Fraction from simplify method.
I am struggling with creation of a to calculate fractions and return in an array[3]. So if nominator is 7 and denominator is 3 it should return {2,1,3}, a fraction part and a integer part. If denominator is 0, the integer division should not be executed and I have to return null (not print it). That is what I am struggling with. My code is below:
public class Main{
public static int[] fraction(int nominator, int denominator){
int quota=0;
int numerator=0;
try{
quota = nominator / denominator;
numerator = nominator % denominator;
}
catch(java.lang.ArithmeticException e)
{
if(denominator==0)
{
quota =0;
numerator=0;
}
}
int [] integerArray ={quota, numerator,denominator};
return integerArray;
}
}
As mentioned in the comments, you can just return early once you checked the denominator is 0.
public static int[] fraction(int nominator, int denominator){
if (denominator == 0){
return null
}
int quota = nominator / denominator;
int numerator = nominator % denominator;
int [] integerArray = {quota, numerator,denominator};
return integerArray;
}
you can proceed in 2 different ways:
you can control if denominator is 0 before the try and return null instantly (as said in the comments)
you used try catch so you can return null into the catch block without further controls because you catch an exception
there should not be any compilation errors so if you get one try to read the console and find what's the problem.
Right now, when running my Rational program I get a 1 when creating a new rational with the numerator being 2 and denominator being 0, and my teacher wants me to replace the denominator with a 1 instead of a 0 but I am unable to and get a stack overflow error whenever trying to add an if in the reduce method that is used to reduce the fractions to their simplest form. I have also tried adding an if statement to the constructor where the rational object containing the numerator and denominator are, but still to no avail. I also have a similar problem when a rational is created with a 0 numerator and 2 in the denominator. It is supposed to return 0/1, but 0 is returned. I believe these two are related, does anyone know what's going on here?
public Rational(int numerator, int denominator) {
int gcd = reduce(numerator, denominator);
num = numerator / gcd;
denom = denominator / gcd;
if(denom == 0)
{
denom = 1;
}
}
private static int reduce(int numerator, int denominator) {
if(denominator == 0) numerator = 1;
return reduce(denominator, numerator % denominator);
}
I don't fully understand the quest and cannot speak to the rational portion of your problem but the stack overflow error is caused by your function reduce. The issue is that there is no endpoint for this function and because it is recursive, function calls will build up on the stack until there is no more space available thus resulting in a stack overflow. The following change will fix the stack overflow error.
private static int reduce(int numerator, int denominator) {
if(denominator == 0) { //assuming this is the end point
numerator = 1;
return numerator; //this ends the recursive call
}
return reduce(denominator, numerator % denominator);
}
If you're looking for a method that finds the greatest common denominator then the following change to your function should work.
private static int reduce(int numerator, int denominator) {
if(denominator == 0) {
return numerator;
}
return reduce(denominator, numerator % denominator);
}
public class Rational{
public Rational (int numerator, denominator){
if (denominator < 0){
system.out.println("Denominator cannot be negative value. Changing rational to have positive denominator...");
denominator = -denominator;
numerator = -numerator;
}
if (denominator == 0){
system.out.println("Denominator cannot be zero, reinput denominator.");
int n = numerator;
int d = denominator;
}
}
//end of initialization
//behaviors
public Rational inverse(int n, d){
if (numerator == 0){
int temp = numerator;
numerator = denominator;
denominator = temp;
}
else system.out.println("Error, the inverse results in division by zero.");
}
public Rational simplify(int n, d){
if (n%d == 0){
return n;
}
else if (n < d){
return simplify (d, n);
}
else return simplify(d, n%d);
numerator = numerator / n;
denominator = denominator /n;
}
}
New Java student here, and I'm running into an "indentifier expected" error on lines 2, 16, and 24. All those lines are public Rational, and the error points to the closing parentheses specifically. I've tried looking through similar questions on here, but I can't figure out what's wrong with mine. From what I saw the error has to do with defining methods outside of a block, but it looks like it's in one to me. Any help would be appreciated!
There are a couple of problems with your program:
You need to declare the type before each parameter for a function. This is what is causing the error message you are getting For instance, you need:
public Rational inverse(int n, int d){
and
public Rational (int numerator, int denominator){
You need to capitalize s in System.
You need to declare the numerator and denominator fields within the Denominator class. For instance:
public class Rational{
int numerator;
int denominator;
The purpose of this code is to calculate (1/2+3/4+...+99/100)^2. But my loop can't be executed correctly.
The result of r1 is 3/4 instead of 99/100, what's wrong with my code?
I think my loop can be run because the y I can get it correctly.
So how can i correct my code and make it able to calculate (1/2+3/4+...+99/100)^2 ? Thank you for answering.
import java.math.BigInteger;
public class Rational {
// Data fields for numerator and denominator
private BigInteger numerator = BigInteger.ZERO;
private BigInteger denominator = BigInteger.ONE;
/** Construct a rational with default properties */
public Rational() {
this(BigInteger.ZERO, BigInteger.ONE);
}
/** Construct a rational with specified numerator and denominator */
public Rational(BigInteger numerator, BigInteger denominator) {
BigInteger gcd=new BigInteger(String.valueOf(gcd(numerator,
denominator)));
BigInteger r1=new
BigInteger(String.valueOf(denominator.compareTo(BigInteger.ZERO)));
this.numerator = (r1.multiply(numerator)).divide(gcd);
this.denominator = (denominator.abs()).divide(gcd);
}
/** Find GCD of two numbers */
private static long gcd(BigInteger n, BigInteger d) {
BigInteger n1 = n.abs();
BigInteger n2 = d.abs();
int gcd = 1;
for (int k = 1; (new BigInteger(String.valueOf(k))).compareTo(n1)<=0 &&
(new BigInteger(String.valueOf(k))).compareTo(n2)<=0; k++) {
if (n1.mod(new BigInteger(String.valueOf(k))).equals(BigInteger.ZERO) &&
n2.mod(new BigInteger(String.valueOf(k))).equals(BigInteger.ZERO))
gcd = k;
}
return gcd;
}
/** Return numerator */
public BigInteger getNumerator() {
return numerator;
}
/** Return denominator */
public BigInteger getDenominator() {
return denominator;
}
/** Add a rational number to this rational */
public Rational add(Rational secondRational) {
BigInteger n =
numerator.multiply(secondRational.getDenominator())
.add(denominator.multiply(sec
ondRational.getNumerator()));
BigInteger d = denominator.multiply(secondRational.getDenominator());
return new Rational(n, d);
}
/** Subtract a rational number from this rational */
public Rational subtract(Rational secondRational) {
BigInteger n =
(numerator.multiply(secondRational.getDenominator()))
.subtract(denominator.multiply(secondRational.getNumerator()));
BigInteger d = denominator.multiply(secondRational.getDenominator());
return new Rational(n, d);
}
/** Multiply a rational number to this rational */
public Rational multiply(Rational secondRational) {
BigInteger n = numerator.multiply(secondRational.getNumerator());
BigInteger d = denominator.multiply(secondRational.getDenominator());
return new Rational(n, d);
}
/** Divide a rational number from this rational */
public Rational divide(Rational secondRational) {
BigInteger n = numerator.multiply(secondRational.getDenominator());
BigInteger d = denominator.multiply(secondRational.numerator);
return new Rational(n, d);
}
/** Compute the square of this rational number*/
public Rational square() {
BigInteger n = numerator.multiply(numerator);
BigInteger d = denominator.multiply(denominator);
return new Rational(n, d);
}
/** toString */
public String toString() {
return numerator + "/" + denominator;
}
}
and this is the testRational class
import java.math.BigInteger;
public class TestRational {
public static void main(String[]args){
int y = 1;
BigInteger i=new BigInteger(String.valueOf(1));
BigInteger a=new BigInteger(String.valueOf(2));
BigInteger b=new BigInteger(String.valueOf(3));
BigInteger c=new BigInteger(String.valueOf(5));
Rational sum = new Rational(BigInteger.ZERO,a);
Rational r0 = new Rational(b,b.add(i));
Rational r2 = new Rational(a,c);
Rational r3 = new Rational(a,c);
Rational s1 = r3.multiply(r2);
Rational s2 = r3.square();
Rational s3 = r2.divide(r3);
Rational r1 = new Rational(i,a);
do{
sum = sum.add(r0);
b = b.add(a);
y++;
}while(y<49);
System.out.println(sum.multiply(sum));
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
System.out.println(r0);
}
}
The purpose of this code is to calculate (1/2+3/4+...+99/100)^2. But my loop can't be executed correctly.
The result of r1 is 3/4 instead of 99/100, what's wrong with my code?
I think my loop can be run because the y I can get it correctly.
So how can i correct my code and make it able to calculate (1/2+3/4+...+99/100)^2 ? Thank you for answering.
The purpose of this code is to calculate (1/2+3/4+...+99/100)^2. But my loop can't be executed correctly.
The result of r1 is 3/4 instead of 99/100, what's wrong with my code?
I think my loop can be run because the y I can get it correctly.
So how can i correct my code and make it able to calculate (1/2+3/4+...+99/100)^2 ? Thank you for answering.
Let's write it less confusingly, without all the unnecessary stuff and confusing loop. The definition of the sum is (1/2 + 3/4 ... 99/100) so let's start by creating all the fractions in the sum:
for (int i = 1; i <= 99; i += 2) {
BigRational t = new BigRational(BigInteger.valueOf(i), BigInteger.valueOf(i + 1));
}
They have to be summed, so there has to be a variable declared outside the loop to sum up all those fractions into:
Rational sum = new Rational();
for (int i = 1; i <= 99; i += 2) {
Rational t = new Rational(BigInteger.valueOf(i), BigInteger.valueOf(i + 1));
sum = sum.add(t);
}
Then square that and you have your answer. I get:
87593039510089573189394173247956745677798336081
-----------------------------------------------
38416307357189261992010230523038591203840000
Which I can't verify but it looks reasonable enough. The expected answer is "a bit less than 502" (because it's the square of 50 terms that are nearly 1, if 0.5 can be called that) and this is close enough.
By the way, stop using String.valueOf everywhere in Rational. Just work with numbers. And BigInteger already implements gcd, you don't have to write your own (less efficient) version. I had to replace this otherwise it took too long.
It's not clear what your sequence of numbers is, but I will go with the following assumption:
If your goal is the simply return the value of (1/2 + 3/4 + 5/6 + ... + 97/98 + 99/100) ^ 2. Then I would suggest the following:
//This method will return the value of (1/2 + 3/4 + 5/6 + ... + 97/98 + 99/100) ^ 2
public int calc(){
double denominator = 2;
double numerator = denominator - 1; //in your sequence, numerator is always 1 less than denominator
double sum = 0;
while(denominator <= 100){
sum = sum + (numerator / denominator); //shorthand sum += (numerator / denominator);
denominator = denominator + 2; //shorthand denominator += 2;
numerator = denominator - 1;
}
return sum * sum; //this is equivalent to sum ^ 2
}