Java Comp Sci nested loops to find closest fraction - java

I want to find the closest fraction equal to 16/76. Whenever i run this i get 1 no matter what. I am doing this for Java class in school.
public class ClassOne {
public static double limit = 16/76;
public static double difference = 1;
public static double numer = 1;
public static double denom = 1;
public static void main(String[] args)
{
for(int i = 1;i<=100;i++)
{
for(int x = 1;x<=100;x++)
{
double temp = limit-(double)(x/i);
System.out.println((x/i));
if(Math.abs(temp) < difference && x/i != 16/76){difference = temp;numer = x; denom = i;
System.out.println("hi");}
}
}
System.out.println(numer + " " + denom);
}
}

A few problems
Use (double)x/(double)i where needed - probably assign to a temp
difference=temp should be difference=Math.abs(temp) or put the abs on the original temp computation
x/i = 16/76 is subject to floating point errors and so may not be hit when you want. May want to use something like 16*i != 76*x which can be computed in integers. I get 21 100.

You're encountering integer division here:
limit - (double)(x/i)
...and here:
public static double limit = 16/76;
Both x and i are int. The cast here will take effect after the division operation has taken effect.
Change your cast so that it applies immediately to one of the variables instead:
limit - ((double)x)/i
Also, consider wherever else you're doing any quotient that isn't with a floating point number (i.e. has a decimal after it or is explicitly cast to a double) - if you need it to be a floating point number, then use the appropriate cast.

Related

Java Euler number result infinity

I try to use a recursive function to calculate the Euler number in Java. It's OK when I enter small numbers into this formula:
But when I try to enter a bigger number like 1000 I get infinity.
Why it's happening. How I can fix it.
import java.util.Scanner;
public class enumber {
public static long fact(int a) {
if(a <= 1) {
return 1;
}
return a * fact(a - 1);
}
public static double calculate(int i) {
double cresult = Math.pow(fact(i), -1);
if(i == 0 ) {
return 1;
}
return cresult+calculate(i-1);
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter i value: ");
int i = sc.nextInt();
double eresult = calculate(i);
System.out.println(eresult);
}
}
output;
Enter i value:
1000
Infinity
That's because you try to calculate the factorial of 1000....which is pretty huge.
Factorial 1000
You try to store it in a long value, but long's
max value is way smaller than 1000!. It basically doesn't fit anymore.
Consider using the class BigInteger (or BigDecimal), its in the default java sdk and you can directly output via println().
However you know the result already, its e, so you might only need to implement the Big-Class for the factorial.
You are exceeding the capacity of a long. But I would suggest you decide how much precision you want for e.
Let's say you want it to have an error of less than .0000001. Continue the iteration for e until the positive delta between your latest computation and the previous is less than or equal to your error.
If you want to take it to extremes, you can always use BigDecimal to increase the accuracy of your results.
I solved that problem by using loops. And for the old algorithm, I changed the fact method type to double. I get rid of Infinity. After that, I face "StackOverflowError".
What is a StackOverflowError?
My new algorithm is;
import java.util.Scanner;
public class enumber2 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
double fact;
double eNumber = 0;
int i = in.nextInt();
while(i>0) {
fact=1;
for(int j=1; j<=i; j++) {
fact = fact * j;
}
eNumber = eNumber +(1.0/fact);
i--;
}
eNumber = eNumber +1;
System.out.println(eNumber);
}
}
even I enter big numbers after a little bit of patient I'm getting results without exception.

Different results from similar methods

In my class I tried to return the sum of: 2^n + 2^(n+1) + 2^(n+2) ... in 2 ways.
Iterative in the first method and recursive in the 2nd one.
This worked as long as numbers weren't too big. Can someone explain to me why those methods return different answers when used with high numbers?
public class Power
{
public static void main(String[] args)
{
System.out.println(iterativ(3));
System.out.println(rekursiv(3));
System.out.println(iterativ(40));
// The recursive one is lower by 10
System.out.println(rekursiv(40));
}
public static int iterativ(int x)
{
int sum = 0;
for (int i = 0; i <= x; i++) {
sum += Math.pow(2, i);
}
return sum;
}
public static int rekursiv(int x)
{
if (x > 0) {
return ((int) Math.pow(2, x) + rekursiv(x - 1));
}
return 1;
}
}
You are using functions that deal with double. You are casting your values to int. Casting values will sooner or later always lead to some inaccurate results, even more so, if you cast from double to int.
The number you were seeing when using 40 as your exponent, was 2147483647, which is in fact Integer.MAX_VALUE, but isn't 2^40. It is rather 2^31-1. The java tutorial has a chapter about the primitive datatypes, which shows you the ranges of each type.
Besides using double you may also want to look at BigDecimal instead.

How does Automatic conversion works in java?

So i had this exercise to add first seven terms from 1 to 7 in order like 1/1!+2/2!+3/3!........7/7!. Below is my code:
public class Problem9
{
public static void main(String args[])
{
int num, i;
float result = 1.0f;
for(num=2; num<=4; num++)
{
i =num;
int fact_num=1;
while(i>=1)
{
fact_num = i*fact_num;
i--;
}
System.out.println("num = "+num);
System.out.println("fact = "+fact_num);
result = result+ (float)num/fact_num;// This line is the one i m
// talking about
}
System.out.printf("The result = %.3f ",result);
}
}
So what is the difference between following line
result = result+ (float)num/fact_num;
and
result = result+ (float)(num/fact_num);
How is the conversion working here.
(float)(num/fact_num) performs int division and casts the result to float, which means that if num < fact_num, the result would be 0.0.
(float)num/fact_num casts num to float and performs floating point division, which means the result won't be 0.0 if num < fact_num (unless num is 0 of course). This is the form you should use in your code, since you are performing divisions whose results are smaller than 1, so int division won't give you the correct result.
(float)(num/fact_num);
Means the result of the two integer divisions casts into a float. The final answer will be a float.
(float)num/fact_num;
Here the int num is cast into a float. the divided by an integer.
For example :
int num = 5;
int fact_num = 2;
System.out.println((float)(num/fact_num));
will give an output of:
2.0

Check if a number is a double or an int

I am trying to beautify a program by displaying 1.2 if it is 1.2 and 1 if it is 1 problem is I have stored the numbers into the arraylist as doubles. How can I check if a Number is a double or int?
Well, you can use:
if (x == Math.floor(x))
or even:
if (x == (long) x) // Performs truncation in the conversion
If the condition is true, i.e. the body of the if statement executes, then the value is an integer. Otherwise, it's not.
Note that this will view 1.00000000001 as still a double - if these are values which have been computed (and so may just be "very close" to integer values) you may want to add some tolerance. Also note that this will start failing for very large integers, as they can't be exactly represented in double anyway - you may want to consider using BigDecimal instead if you're dealing with a very wide range.
EDIT: There are better ways of approaching this - using DecimalFormat you should be able to get it to only optionally produce the decimal point. For example:
import java.text.*;
public class Test
{
public static void main(String[] args)
{
DecimalFormat df = new DecimalFormat("0.###");
double[] values = { 1.0, 3.5, 123.4567, 10.0 };
for (double value : values)
{
System.out.println(df.format(value));
}
}
}
Output:
1
3.5
123.457
10
Another simple & intuitive solution using the modulus operator (%)
if (x % 1 == 0) // true: it's an integer, false: it's not an integer
I am C# programmer so I tested this in .Net. This should work in Java too (other than the lines that use the Console class to display the output.
class Program
{
static void Main(string[] args)
{
double[] values = { 1.0, 3.5, 123.4567, 10.0, 1.0000000003 };
int num = 0;
for (int i = 0; i < values.Length; i++ )
{
num = (int) values[i];
// compare the difference against a very small number to handle
// issues due floating point processor
if (Math.Abs(values[i] - (double) num) < 0.00000000001)
{
Console.WriteLine(num);
}
else // print as double
{
Console.WriteLine(values[i]);
}
}
Console.Read();
}
}
Alternatively one can use this method too, I found it helpful.
double a = 1.99;
System.out.println(Math.floor(a) == Math.ceil(a));
You can use:
double x=4;
//To check if it is an integer.
return (int)x == x;

Random Number Generator

I need to write a program in Java to generate random numbers within the range [0,1] using the formula:
Xi = (aXi-1 + b) mod m
assuming any fixed int values of a, b & m and X0 = 0.5 (ie i=0)
How do I go about doing this?
i tried doing this but it's obviously wrong:
int a = 25173, b = 13849, m = 32768;
double X_[i];
for (int i = 1; i<100; i++)
X_[i] = (a*(X_[i]-1) + b) % m;
double X_[0] = 0.5;
double double = new double();
System.out.println [new double];
Here are some hints:
int a, d, m, x;
Multiplication is * and mod is %.
update
Okay, I'll give you a little more of a hint. You only need one X, you don't need all these arrays; since you're only using integers you don't need any floats or doublts.
The important line of code will be
x = (a * x + b) % m ;
You don't need another x there because the x on the right hand side of the = is the OLD x, or xi-1; the one on the left side will be your "new" x, or xi.
Now, from there, you need to write the Java wrapper that will let you make that a method, which means writing a class.
Sounds like homework... so I won't give you a solution in code.
Anyways you need a linear congruential generator.
HINT: You need to write that mathematical formula as a function.
Steps:
Make a class.
Add the required state as member to the class.
Make a function within the class. Have it take input as necessary.
Write the formula for the congruential generator in Java (look up math operations in Java).
Return the result.
My Java is rusty, so I can't say I'm sure about this but these are probably errors:
int a = 25173, b = 13849, m = 32768;
double X_[i];//You need to define a constant array or use perhaps a list, you can't use i without defining it
for (int i = 1; i<100; i++)
X_[i] = (a*(X_[i]-1) + b) % m;
double X_[0] = 0.5;
double double = new double(); //You can't name a variable double, also types like double, don't need to be newed (I think)
System.out.println [new double]; //println uses () not [], in Java I think all functions need to use (), its not implied
EDIT:
Bongers:
[ ] are special symbols, if you intended for your variable to be named "X_[ i ]" that won't work. If you intended to make an array, you're making it too complicated.
You need to figure out if theY original equation was Xi - 1 or X(i-1) as that makes a huge difference in your programming. Xi - 1 is just one less than Xi. X(i-1) is the previous random number.
try doing some beginner java tutorials online. Here's a good place to start. Really try to understand the tutorials before continuing on to your problem.
Think about your problem this way.[Assuming the equation is X(i-1)] To generate the 3rd random number, X3, you will need to generate X2, which needs X1, which needs X0. But you have X0. So for any Xi, start with X0, generate X1, then generate X2, etc.. up until Xi.
You'll probably don't need to look into recursion like I first suggested.
A linear congruential generator is basically an expression which modifies a given value to produce the next value in the series. It takes the form:
xi+1 = (a.xi + b) mod m
as you've already specified (slightly differently: I was taught to always put xi+1 on the left and I still fear my math teachers 25 years later :-), where values for a, b and m are carefully chosen to give a decent range of values. Note that with the mod operator, you will always end up with a value between 0 and m-1 inclusive.
Note also that the values tend to be integral rather than floating point so if, as you request, you need a value in the range 0-0.999..., you'll need to divide the integral value by m to get that.
Having explained how it works, here's a simple Java program that implements it using values of a, b and m from your question:
public class myRnd {
// Linear congruential values for x(i+1) = (a * x(i) + b) % m.
final static int a = 25173;
final static int b = 13849;
final static int m = 32768;
// Current value for returning.
int x;
public myRnd() {
// Constructor simply sets value to half of m, equivalent to 0.5.
x = m / 2;
}
double next() {
// Calculate next value in sequence.
x = (a * x + b) % m;
// Return its 0-to-1 value.
return (double)x / m;
}
public static void main(String[] args) {
// Create a new myRnd instance.
myRnd r = new myRnd();
// Output 20 random numbers from it.
for (int i = 0; i < 20; i++) {
System.out.println (r.next());
}
}
}
And here's the output, which looks random to me anyway :-).
0.922637939453125
0.98748779296875
0.452850341796875
0.0242919921875
0.924957275390625
0.37213134765625
0.085052490234375
0.448974609375
0.460479736328125
0.07904052734375
0.109832763671875
0.2427978515625
0.372955322265625
0.82696533203125
0.620941162109375
0.37451171875
0.006134033203125
0.83465576171875
0.212127685546875
0.3128662109375
I would start by creating a class that holds a, b, m, the latest x (initialized to 0.5), and a method like getNextNumber().
public class generate_random_numbers {
public static void main(String[] args) {
int a = 25173, b = 13849, m = 32768;
Double[] X_ = new Double[100];
X_[0] = 0.5;
for (int i = 1; i < 100; i++) {
X_[i] = (a * X_[i - 1] + b) % m;
X_[i] = X_[i] / m;
System.out.println("X_[" + i + "] = " + X_[i]);
}
}
}

Categories