I've checked many stackOverflow questions about operations with objects but I haven't find the solution.
My task is to multiply and divide two objects with these constructors:
public class Fraction {
private int denom;
private int counter;
public Fraction() {
this.counter = 0;
this.denom = 1;
}
public Fraction(int counter) {
this.counter = counter;
this.denom = 1;
}
public Fraction(int counter, int denom) {
this.counter = counter;
if (denom == 0) {
this.denom = 1;
} else
this.denom = denom;
}
}
What would be inside the "multiply" and "divide" methods?
public Fraction multiply(Fraction other) {
}
public Fraction divide(Fraction other) {
}
if this is what I need to use:
Fraction frac1 = new Fraction (2);
Fraction frac2 = new TortSzam(3,4);
fracResult = frac1.divide(frac2);
and the result is: 2.6666666666666665
What I tried by other StackOverflow Questions:
public Fraction multiply(Fraction other) {
final Fraction multi = this;
BigInteger result = new BigInteger;
result.multiply(other);
}
But didn't work.
Thanks in advance.
Multiplying two fractions just means multiplying the numerators, and then dividing that product by the multiplication of the denominators. So you may try:
public Fraction multiply(Fraction other) {
int counter = other.getCounter() * this.counter;
int denim = other.getDenominator() * this.denom;
return new Fraction(counter, denom);
}
I will leave the implementation of division up to you. As a hint, the code would be very similar to the above except that you would use the inverse of one (but not both) of the two fraction inputs.
Related
I'm trying to use Junit for the first time but I'm facing some unexpected failure.
Here is the failure message:
org.opentest4j.AssertionFailedError: expected: <2> but was: <19>.
It would be great if someone will be able to help me understand where is my error.
I spend more than 30 minutes in trying to understand the reason behind it and I can't. I guess I need to do a minor change somewhere.
public class Fraction {
private int numerator;
private int denominator;
public int getNumerator() {
return numerator;
}
public int getDenomonator() {
return denominator;
}
public Fraction(int n, int d) {
numerator = n;
denominator = d;
}
/**
* This method is adding other fraction
* to our current(this) fraction
* #param otherFraction
*/
public void add(Fraction otherFraction) {
int a = numerator;
int b = denominator;
int c = otherFraction.getNumerator();
int d = otherFraction.getDenomonator();
numerator = a * d + b * c;
denominator = b * d;
int min = denominator;
if (numerator < denominator) {
min = numerator;
}
int commonDiv = 1;
for (int i = 1; i <= min; i++) {
if ((numerator % i == 0) && (denominator % 1 == 0)) {
commonDiv = i;
}
}
numerator = numerator / commonDiv;
denominator = denominator / commonDiv;
if (numerator == 0) denominator = 1;
}
}
Test:
class FreactionTest {
#Test
void test() {
Fraction f1 = new Fraction(3,4);
Fraction f2 = new Fraction(5,6);
f1.add(f2);
assertEquals(f1.getNumerator(),19);
assertEquals(f1.getDenomonator(),12);
}
#Test
void testAddNegative() {
Fraction f1 = new Fraction(3,4);
Fraction f2 = new Fraction(-3,4);
f1.add(f2);
assertEquals(f1.getNumerator(),0);
assertEquals(f1.getDenomonator(),1);
}
}
I expected the code to run successfully.
It looks like you have your expected/actual backwards in the call to assertEquals(). According to the docs here, the first argument is the expected value, and the second argument is the actual value. So you need to switch your arguments, since right now you're hard-coding the actual result to be 19. The call you're trying to test should be the second argument, and the value you expect to be returned should be the first argument. You're doing it in all your other assertEquals() calls also, so be sure to change those as well.
public class Rational {
int num, denom; /*I'm building an object named "Rational, which takes in two int values, num and denom, and represent them as a rational number(num/denom)*/
public Rational(int a, int b){//this is the constructor
this.num = a;
this.denom = b;
}
public Rational(){//this is just another form of constructor
this.num = 0;
this.denum = 0;
}
public static void printRational(Rational x){/*this is the method that prints the rational number in a fractional format*/
System.out.println(x.num+"/"+x.denom);
}
public static int gcd(int a, int b){/*this is the method which finds the greatest common denominator of numerator of denominator. This will be used to simplify the fraction*/
if(b == 0){
return a;
}
else{
return gcd(b, a%b);
}
}
public static Rational add(Rational x, Rational y){/*this is a method which adds the two rational numbers(or objects) together, then simplify it utilizing the gcd method*/
Rational z = new Rational();
z.denom = (x.denom * y.denom);
z.num = y.num*x.denom + x.num*y.denom;
z.denom = z.denom/gcd(z.num, z.denom);
z.num = z.num/gcd(z.num, z.denom);
return z;
}
public static void main(String[] args) {
Rational y = new Rational(1, 2); //1st Rational Object: y
Rational z = new Rational(2, 6); //2nd Rational Object: z
printRational(add(y, z)); //implementing the method
//result? so far so good. I get the correct result
}
}
The problem I'm facing is I don't understand is that why this won't work instead and give me an error.
public static Rational add(Rational x, Rational y){
Rational z = new Rational();
int a = (x.denom * y.denom);
int b = y.num*x.denom + x.num*y.denom;
z.denom = a/gcd(z.num, z.denom);
z.num = b/gcd(z.num, z.denom);
return z;
}
Why would this give me an error message: "Exception in thread "main" java.lang.ArithmeticException: / by zero
at Rational.add(Rational.java:47)
at Rational.main(Rational.java:58)" when the instances of the object are int types and I'm temporarility storing the value into int a, b; Help me please if you see something I don't see!! Thank you.
I do not know what is the exact problem, when you say "It is not working". It would have been helpful if you could tell what error is it giving. However, from what you have said, Could it be because you have not initialized z.num and z.denom and are sending them to gcd() ?? They will both be zero, as they are primitive data type "int" so your gcd method will return 0 and cause an exception.
public static Rational add(Rational x, Rational y){
Rational z = new Rational();
int a = (x.denom * y.denom);
int b = y.num*x.denom + x.num*y.denom;
z.denom = a/gcd(z.num, z.denom); <--------------
z.num = b/gcd(z.num, z.denom); <--------------
return z;
}
You are using the wrong implementation for dividing with gcd as the number changes in this case.
z.denom = z.denom/gcd(z.num, z.denom);
z.num = z.num/gcd(z.num, z.denom);//z.denom is changed here.
The z.denom can be 0 as it is changed so gcd is 0 and hence the exception.
So what you can do is.
int gcd = gcd(z.num, z.denom);
z.denom /= gcd;
z.num /= gcd;
Also this fails when either of num or denom is a 0.
I think my program is skipping my while loop, but I'm honestly not sure exactly what is happening. The function is supposed to reduce fractions by finding the GCD and then dividing numerator and denominator by that number.
class Rational {
private int numerator, denominator;
//Constructor
public Rational (int num, int den) {
numerator = num;
denominator = den;
}
//Method for multiplying fractions
public Rational times (Rational that) {
Rational x = new Rational (this.numerator*that.numerator, this.denominator*that.denominator);
x = x.reduce();
return x;
}
//Method for displaying fractions as strings
public String toString() {
return new String(numerator+"/"+denominator);
}
//Method for adding fractions
public Rational plus(Rational that) {
Rational x = new Rational ((this.numerator*that.denominator)+(that.numerator*this.denominator),
this.denominator*that.denominator);
//x = x.reduce();
return x;
}
//Method for subtracting fractions
public Rational minus(Rational that) {
Rational x = new Rational ((this.numerator*that.denominator)-(that.numerator*this.denominator),
this.denominator*that.denominator);
//x = x.reduce();
return x;
}
//Method for dividing fractions
public Rational divideBy(Rational that) {
Rational x = new Rational (this.numerator*that.denominator, this.denominator*that.numerator);
//x = x.reduce();
return x;
}
public Rational reduce() {
int a = Math.abs(this.numerator);
int b = Math.abs(this.denominator);
int c = Math.min(a, b);
System.out.println(c);
System.out.println(a%c);
System.out.println(b%c);
if (a==0) {
return new Rational (0,1);
}
else {
while (((a%c)!= 0) && ((b%c)!= 0)) {
c = c-1;
System.out.println(c);
}
System.out.println(c);
return new Rational (this.numerator/c,this.denominator/c);
}
}
}
public class RationalTester {
public static void main(String[] args) {
Rational x = new Rational (6,4); //The fraction 6/4
Rational y = new Rational (5,2); //The fraction 5/2
Rational z = x.times(y); //Their product
Rational w = x.plus(y); //Their sum
Rational v = x.minus(y); //Their difference
Rational u = x.divideBy(y); //Their quotient
JOptionPane.showMessageDialog(null, x.toString()+" * "+y.toString()+" = "+z.toString());
JOptionPane.showMessageDialog(null, x.toString()+" + "+y.toString()+" = "+w.toString());
JOptionPane.showMessageDialog(null, x.toString()+" - "+y.toString()+" = "+v.toString());
JOptionPane.showMessageDialog(null, x.toString()+" / "+y.toString()+" = "+u.toString());
}
}
I'm getting the absolute value of the numerator and denominator to ensure that if the fraction is negative I'll be keeping that at the end. If the numerator is 0, I was asked to return (0,1). The question is about the while loop... it seems that it's being skipped completely. Any suggestions?
Because always its condition is false.
In the first lines you set c equal to either a or b. So there are two possibilities:
If c == a, then a%c will be zero. So the while condition is false.
If c == b, then b%c will be zero. So the while condition is false.
I've been racking my brain all morning trying to come up with the following algorithm, this is especially frustrating because I'm sure that it's possible.
What I need is a class that has a function that returns boolean. It can be called any number of times and will return true XX% of the time. This CANNOT be a random distribution, for example:
If the ratio X is set to 0.6 and the function is called 100 times, we need to return exactly 60 true results. In which order "left overs" are used doesn't matter, for example: if the function was called 99 times it would be OK to return either 59 or 60 true values.
The trick here is that the ratio needs to be variable.
For some setup, I'm working in a multi threaded environment so I'm keeping my "hitNumber" variable in an AtomicLong in order to avoid synchronization issues.
Thanks!
If all you want is to maintain the overall percentage, just keep track of the percentage so far (probably as an explicit rational), and return true if you're under the target percentage, or false if you're over it.
Your criterion that it can't be random is pretty ill-defined. I suppose you mean that the quantity T/(T+F) is as close to the ratio as integer T and F will allow.
So you'll end up with something like this:
class TrueFalseGenerator {
final double ratio;
long nTrue, nFalse;
TrueFalseGenerator(double ratio) {
this.ratio = ratio;
nTrue = nFalse = 0;
}
synchronized boolean next() {
long den = nTrue + nFalse;
if (den == 0 || (double)nTrue / den < ratio) {
nTrue++;
return true;
} else {
nFalse++;
return false;
}
}
}
To build on Ben's answer, you can maintain static class variables to keep track of past function calls. Something like:
bool myFunc( float true_percentage ) {
count++; // where count and count_true are class static variables initialized to zero.
if ( float( count_true ) / count >= true_percentage )
return false;
count_true++;
return true;
}
This version uses only integer arithmetic and doesn't need any counter:
public class Distribution {
private int numerator;
private int denominator;
private int error;
public Distribution(int numerator, int denominator) {
this.numerator = numerator;
this.denominator = denominator;
}
public synchronized boolean next() {
error += numerator;
if (error >= denominator) {
error %= denominator;
return true;
}
return false;
}
}
Usage:
Distribution dist = new Distribution(6, 10); // 6 trues out of 10
dist.next(); // get next bool
//algorithm
//1st call randomize(x) from main with x as percentage
//this calls fischershuffle to shuffle the boolean array
//den calls to return bool are randomized with x trues and 100-x falses per 100 calls
class A{
public static int count=0;
public static boolean fill[]=new boolean[100];
public static void randomize(double x)
{
double totaltrue=x*100;
double totalfalse=100-totaltrue;
for(int i=0;i<100;i++)
{
if(totaltrue>0.00)
{
fill[i]=true;
totaltrue-=1.00;
}
else
{
fill[i]=false;
totalfalse-=1.00;
}
}
fill=fischershuffle(fill);
}
static boolean fischershuffle(boolean[] ar)
{
Random rnd = new Random();
for (int i = ar.length - 1; i > 0; i--)
{
int index = rnd.nextInt(i + 1);
boolean a = ar[index];
ar[index] = ar[i];
ar[i] = a;
}
return ar;
}
public static boolean retunbool()
{
if(count<=100)
{
count++;
return fill[count];
}
else{
count=0;//resets after 100 for next 100 calls
}
What I have to do is take 2 random variables for a fraction, 1 to 1000, and check to see if they are in reduced terms already or not. I do this 1,000 times and keep track of whether it was or wasn't in reduced terms.
Here is the main class
import java.util.*;
public class ratio1 {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int nonReducedCount = 0; //counts how many non reduced ratios there are
for(int i =1; i<=1000; i++){
Random rand = new Random();
int n = rand.nextInt(1000)+1; //random int creation
int m = rand.nextInt(1000)+1;
Ratio ratio = new Ratio(n,m);
if (ratio.getReduceCount() != 0 ){ // if the ratio was not already fully reduced
nonReducedCount++; // increase the count of non reduced ratios
}
}
int reducedCount = 1000 - nonReducedCount; //number of times the ratio was reduced already
double reducedRatio = reducedCount / nonReducedCount; //the ratio for reduced and not reduced
reducedRatio *= 6;
reducedRatio = Math.sqrt(reducedRatio);
System.out.println("pi is " + reducedRatio);
}
}
And here is the class I am not sure about. All I want from it is to determine whether or not the fraction is already in simplest form. When I currently try to run it, it is giving me an error; "Exception in thread "main" java.lang.StackOverflowError
at Ratio.gcd (Ratio.java:67)
at Ratio.gcd (Ratio.java:66)"
public class Ratio{
protected int numerator; // numerator of ratio
protected int denominator; //denominator of ratio
public int reduceCount = 0; //counts how many times the reducer goes
public Ratio(int top, int bottom)
//pre: bottom !=0
//post: constructs a ratio equivalent to top::bottom
{
numerator = top;
denominator = bottom;
reduce();
}
public int getNumerator()
//post: return the numerator of the fraction
{
return numerator;
}
public int getDenominator()
//post: return the denominator of the fraction
{
return denominator;
}
public double getValue()
//post: return the double equivalent of the ratio
{
return (double)numerator/(double)denominator;
}
public int getReduceCount()
//post: returns the reduceCount
{
return reduceCount;
}
public Ratio add(Ratio other)
//pre: other is nonnull
//post: return new fraction--the sum of this and other
{
return new Ratio(this.numerator*other.denominator+this.denominator*other.numerator,this.denominator*other.denominator);
}
protected void reduce()
//post: numerator and denominator are set so that the greatest common divisor of the numerator and demoninator is 1
{
int divisor = gcd(numerator, denominator);
if(denominator < 0) divisor = -divisor;
numerator /= divisor;
denominator /= divisor;
reduceCount++;
}
protected static int gcd(int a, int b)
//post: computes the greatest integer value that divides a and b
{
if (a<0) return gcd(-a,b);
if (a==0){
if(b==0) return 1;
else return b;
}
if (b>a) return gcd(b,a);
return gcd(b%a,a);
}
public String toString()
//post:returns a string that represents this fraction.
{
return getNumerator()+"/"+getDenominator();
}
}
Here are the lines of the error in the Ratio class;
if (b>a) return gcd(b,a);
return gcd(b%a,a);
A fraction is reducible if its GCD is greater than 1. You can compute the GCD with the static method given in Ratio, so you could instead use:
...
int n = rand.nextInt(1000)+1;
int m = rand.nextInt(1000)+1;
if(Ratio.gcd(n,m) == 1) {
nonReducedCount++;
}
This saves you from instantiating a new Ratio instance.
If that method doesn't work for you, you can always use your own GCD calculator. This one is recursive too and similar to the one in Ratio:
public static int gcd(int a, int b) { return b==0 ? a : gcd(b,a%b); }
You could Google it for non-recursive methods if the StackOverflowError is still a problem.