The Leibniz formula for pi is: pi/4 = 1 - 1/3 + 1/5 - 1/7 + 1/9... I am trying to write this in Java but am running into a problem where the output is always 4 (which is not the value of pi). I put my code in a java visualizer and it seems that the problem is that when the code falls into the else statement, it is not subtracting (1-denominator) from pi and that is making the prevPi value and the pi value the same which is causing the do/while loop to end. Does anyone know how I can fix this?
My code:
public static float piCalculatorLeibniz() {
float pi = 0;
int denominator = 1;
float prevPi = 0;
boolean keepGoing = true;
int i = 0;
while (keepGoing == true) {
prevPi = pi;
if (i % 2 == 0) {
pi += (1/denominator);
} else {
pi -= (1/denominator);
}
i++;
denominator += 2;
if (pi == prevPi) {
keepGoing = false;
}
}
pi *= 4;
return pi;
}
You're right. 4 is in fact not the value of Pi.
The problem is that the denominator variable is an int so 1/denomenator is int/int so the result is 0. That makes you exit the loop after just one iteration since pi == prevPi
Just change the denominator type to a double (or float) and you'll get the right answer.
Also, you don't need to write while(keepGoing == true). The variable keepGoing is already a boolean, you can write simply while(keepGoing)
Edit:
I enjoyed playing with this code, so here's a slightly shorter version that's more accurate due to the use of double. It also seems to converge quite a lot faster:
double pi = 0, denominator = 1, prevPi = 1;
while (pi != prevPi) {
prevPi = pi;
pi += (1 / denominator) - (1 / (denominator + 2));
denominator += 4;
}
return pi * 4;
The problem is that integer division results in an integer, not a float or double.
1 / 3 is 0.
To avoid this, you can switch to using a float for the denominator instead of an int.
float denominator = 1.0f;
Make your, all your operands are floating point types. Otherwise your result is an integer.
See Java Language Specifications:
If the promoted type is float or double, then floating-point arithmetic is performed.
Also, on most platforms you can use double without any performance penalty, but this is another topic. ;-)
I have to compute pi to six decimal precision using the leibniz series and I managed to do it except the assigment has some restrictions.
pi / 4 = 1 -1/3 + 1/5 - 1/7 ....
"
cannot utilize the math library π in your computation - direct or indirect. Use ONLY the delta (difference) of your running computation to determine when to stop your loop
"
I do not understand what this means by difference of your running computation. Another way I was told was "When your computed value ceases to change then your loop can stop"
package com.company;
public class Main {
public static void main(String[] args) {
double series = 0;
double denominator = 1;
double numerator = 1;
double pi;
double testingPi;
double formattedTestingPi = 0;
double formattedMathPi = Math.round(Math.PI * 1000000.0) / 1000000.0;
int max = 1200000;
int iterations = 0;
for(int i = 1; i < max;i++)
{
if((i % 2) != 0)
{
series = series + (numerator/denominator);
}
else if((i % 2) == 0)
{
series = series + ((numerator/denominator) * -1);
}
denominator = denominator + 2;
testingPi = series * 4;
formattedTestingPi = (Math.round(testingPi * 1000000.0))/1000000.0;
if( formattedTestingPi == formattedMathPi)
{
iterations = i;
i = max;
System.out.println("We stop");
}
}
pi = series * 4;
System.out.println("Number of Iterations :" + iterations);
System.out.println("Unformatted Series :" + series);
System.out.println("Unformatted Math Library PI:" + Math.PI);
System.out.println("Unformatted Computed PI:" + pi);
System.out.println("Formatted Computed PI:" + formattedTestingPi);
System.out.println("Formatted Math Library PI:" + formattedMathPi);
}
}
I do not want the solution to the assignment, I just want to know
what does delta of computation mean and how is it different what I'm doing right now?
Output
Number of Iterations :1181461
Unformatted Series :0.7853983749998679
Unformatted Math Library PI:3.141592653589793
Unformatted Computed PI:3.1415934999994715
Formatted Computed PI:3.141593
Formatted Math Library PI:3.141593
The assignment is
The following method can be used to approximate the value of Pi:
Pi/4 = 1 – (1/3) + (1/5) – (1/7) + (1/9) – (1/11) + …
Write a program that allows the user to specify the number of iterations used in this approximation and display the approximated value of Pi. Test the program for small, medium and large number of iterations.
It compiles but it not giving me the answers I want. For instance when I put in 1, it gives me 1/3 instead of 8/3. When I pretty much any other number, it just bugs out and I can't get any output.
import java.util.*;
import java.io.*;
public class LabFiveUnitFour {
public static void main(String[] args) {
double n, pi=1, count=1, amount;
Scanner input = new Scanner(System.in);
System.out.println("How many pi iterations do you want?");
amount = input.nextDouble();
n = amount;
do {
pi = ((Math.pow(-1, n)) / (2 * n + 1));
} while (!(count == amount));
{
n = n - 1;
pi = pi + ((Math.pow(-1, n)) / (2 * n + 1));
count++;
}
pi = 4 * (1 - pi);
System.out.println(pi + "");
}
}
You have a do/while loop that is controlled by comparing count and amount and the body of that loop is not doing anything to modify either of those variables. The result will be that the loop will never exit.
This easy program program computes an estimate of pi by simulating dart throws onto a square.
Сonditions: Generate a random floating-point number and transform it so that it is between -1 and 1.
Store in x. Repeat for y. Check that (x, y) is in the unit circle, that is, the distance between (0, 0) and (x, y) is <= 1.
After this, need to find the ratio hits / tries is approximately the same as the ratio circle area / square area = pi / 4. (square is 1 per 1).
Code:
public class MonteCarlo {
public static void main(String[] args)
{
System.out.println("Number of tries");
Random generator = new Random(42);
Scanner in = new Scanner(System.in);
int tries = in.nextInt();
int hits = 0;
double x, y;
for (int i = 1; i <= tries; i++)
{
// Generate two random numbers between -1 and 1
int plusOrMinus = generator.nextInt(1000);
if (plusOrMinus > 500) x = generator.nextDouble();
else x = -generator.nextDouble();
plusOrMinus = generator.nextInt(10000);
if (plusOrMinus > 5000) y = generator.nextDouble();
else y = -generator.nextDouble();
if (Math.sqrt((x * x) + (y * y)) <= 1) // Check whether the point lies in the unit circle
{
hits++;
}
}
double piEstimate = 4.0 * hits / tries;
System.out.println("Estimate for pi: " + piEstimate);
}
}
Testing output:
Actual output Expected output
-----------------------------------------------
Number of tries Number of tries
1000 1000
- Estimate for pi: 3.176 Estimate for pi: 3.312
Actual output Expected output
-----------------------------------------------------
Number of tries Number of tries
1000000 1000000
- Estimate for pi: 3.141912 Estimate for pi: 3.143472
Maybe, does exist other approaches to find this solution?
Any suggestions.
For generating the random double between -1 and 1, try:
generator.nextDouble() * 2 - 1
BTW: If you keep initializing your random with a static seed, you'll always get the same result. Otherwise, if you are concerned that your result is not good enough, keep in mind that the Monte Carlo is only an approximation. After all, it's based on random numbers, so the result will vary from the sample solution ;-)
A generalized solution to turn a Uniform(0,1) into a Uniform(a,b) (where a < b) is
(b - a) * generator.nextDouble() + a
As #winSharp93 pointed out, you should expect variation but you can quantify the margin of error as a statistical confidence interval. If you calculate
halfWidth = 1.96 * Math.sqrt(piEstimate * (4.0 - piEstimate) / tries);
then the actual value of pi should fall between piEstimate - halfWidth and piEstimate + halfWidth 95% of the time. You can see from the halfWidth calculation that the range containing pi will shrink (but not linearly) as the number of tries is increased. You can adjust the confidence level from 95% to other values by replacing 1.96 with an alternative scale value out of a Standard Normal table.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 7 years ago.
Improve this question
Is there a library that will convert a Double to a String with the whole number, followed by a fraction?
For example
1.125 = 1 1/8
I am only looking for fractions to a 64th of an inch.
Your problem is pretty simple, because you're assured the denominator will always divide 64. in C# (someone feel free to translate a Java version):
string ToMixedFraction(decimal x)
{
int whole = (int) x;
int denominator = 64;
int numerator = (int)( (x - whole) * denominator );
if (numerator == 0)
{
return whole.ToString();
}
while ( numerator % 2 == 0 ) // simplify fraction
{
numerator /= 2;
denominator /=2;
}
return string.Format("{0} {1}/{2}", whole, numerator, denominator);
}
Bonus: Code Golf
public static string ToMixedFraction(decimal x) {
int w = (int)x,
n = (int)(x * 64) % 64,
a = n & -n;
return w + (n == 0 ? "" : " " + n / a + "/" + 64 / a);
}
One problem you might run into is that not all fractional values can be represented by doubles. Even some values that look simple, like 0.1. Now on with the pseudocode algorithm. You would probably be best off determining the number of 64ths of an inch, but dividing the decimal portion by 0.015625. After that, you can reduce your fraction to the lowest common denominator. However, since you state inches, you may not want to use the smallest common denominator, but rather only values for which inches are usually represented, 2,4,8,16,32,64.
One thing to point out however, is that since you are using inches, if the values are all proper fractions of an inch, with a denominator of 2,4,8,16,32,64 then the value should never contain floating point errors, because the denominator is always a power of 2. However if your dataset had a value of .1 inch in there, then you would start to run into problems.
How about org.apache.commons.math ? They have a Fraction class that takes a double.
http://commons.apache.org/math/api-1.2/org/apache/commons/math/fraction/Fraction.html
You should be able to extend it and give it functionality for the 64th. And you can also add a toString that will easily print out the whole number part of the fraction for you.
Fraction(double value, int
maxDenominator) Create a fraction
given the double value and maximum
denominator.
I don't necessarily agree, base on the fact that Milhous wants to cover inches up to 1/64"
Suppose that the program demands 1/64" precision at all times, that should take up 6 bits of the mantissa. In a float, there's 24-6 = 18, which (if my math is right), should mean that he's got a range of +/- 262144 + 63/64"
That might be enough precision in the float to convert properly into the faction without loss.
And since most people working on inches uses denominator of powers of 2, it should be fine.
But back to the original question, I don't know any libraries that would do that.
Function for this in a C-variant called LPC follows. Some notes:
Addition to input value at beginning is to try to cope with precision issues that otherwise love to wind up telling you that 5 is 4 999999/1000000.
The to_int() function truncates to integer.
Language has a to_string() that will turn some floats into exponential notation.
string strfrac(float frac) {
int main = to_int(frac + frac / 1000000.0);
string out = to_string(main);
float rem = frac - to_float(main);
string rep;
if(rem > 0 && (to_int(rep = to_string(rem)) || member(rep, 'e') == Null)) {
int array primes = ({ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47 });
string base;
int exp;
int num;
int div;
if(sscanf(rep, "%se%d", base, exp) == 2) {
num = to_int(replace(base, ".", ""));
div = to_int(pow(10, abs(exp)));
} else {
rep = rep[2..];
num = to_int(rep);
div = to_int(pow(10, strlen(rep)));
}
foreach(int prime : primes) {
if(prime > num)
break;
while((num / prime) * prime == num && (div / prime) * prime == div) {
num /= prime;
div /= prime;
}
}
out += " " + num + "/" + div;
}
return out;
}
i wrote this for my project i hope it could be usefull:
//How to "Convert" double to fraction("a/b") - kevinlopez#unitec.edu
private boolean isInt(double number){
if(number%2==0 ||(number+1)%2==0){
return true;
}
return false;
}
private String doubleToFraction(double doub){
//we get the whole part
int whole = (int)doub;
//we get the rest
double rest = doub - (double)whole;
int numerator=1,denominator=1;
//if the whole part of the number is greater than 0
//we'll try to transform the rest of the number to an Integer
//by multiplying the number until it become an integer
if(whole >=1){
for(int i = 2; ; i++){
/*when we find the "Integer" number(it'll be the numerator)
* we also found the denominator(i,which is the number that transforms the number to integer)
* For example if we have the number = 2.5 when it is multiplied by 2
* now it's 5 and it's integer, now we have the numerator(the number (2.5)*i(2) = 5)
* and the denominator i = 2
*/
if(isInt(rest*(double)i)){
numerator = (int)(rest*(double)i);
denominator = i;
break;
}
if(i>10000){
//if i is greater than 10000 it's posible that the number is irrational
//and it can't be represented as a fractional number
return doub+"";
}
}
//if we have the number 3.5 the whole part is 3 then we have the rest represented in fraction 0.5 = 1/2
//so we have a mixed fraction 3+1/2 = 7/2
numerator = (whole*denominator)+numerator;
}else{
//If not we'll try to transform the original number to an integer
//with the same process
for(int i = 2; ; i++){
if(isInt(doub*(double)i)){
numerator = (int)(doub*(double)i);
denominator = i;
break;
}
if(i>10000){
return doub+"";
}
}
}
return numerator+"/"+denominator;
}
My code looks like this.
public static int gcd(int a, int b)
{
if (b == 0)
return a;
else
return gcd(b, a % b);
}
public static String doubleToStringFraction(Double d)
{
StringBuffer result = new StringBuffer(" " + ((int) Math.floor(d)));
int whole = (int) ((d - Math.floor(d)) * 10000);
int gcd = gcd(whole, 10000);
result.append(" " + (whole / gcd) + "/" + 10000 / gcd + " ");
return result.toString();
}
As several others have poited out, fractions of 64 can be precicely represented by IEEE-floats. This means we can also convert to a fraction by moving and masking bits.
This is not the place to explain all details of floating point representations, please refer to wikipedia for details.
Briefly: a floating point number is stored as (sign)(exp)(frac) where sign is 1 bit, exp is 11 bits and frac is the fraction part (after 1.) and is 52 bits. This is enterpreted as the number:
(sign == 1 ? -1 : 1) * 1.(frac) * 2^(exp-1023)
Thus, we can get the 64th by moving the point accoring to the exponent and masking out the 6 bits after the point. In Java:
private static final long MANTISSA_FRAC_BITMAP = 0xfffffffffffffl;
private static final long MANTISSA_IMPLICIT_PREFIX = 0x10000000000000l;
private static final long DENOM_BITMAP = 0x3f; // 1/64
private static final long DENOM_LEN = 6;
private static final int FRAC_LEN = 52;
public String floatAsFrac64(double d) {
long bitmap = Double.doubleToLongBits(d);
long mantissa = bitmap & MANTISSA_FRAC_BITMAP | MANTISSA_IMPLICIT_PREFIX;
long exponent = ((bitmap >> FRAC_LEN) & 0x7ff) - 1023;
boolean negative = (bitmap & (1l << 63)) > 0;
// algorithm:
// d is stored as SE(11)F(52), implicit "1." before F
// move point to the right <exponent> bits to the right:
if(exponent > FRAC_LEN) System.out.println("warning: loosing precision, too high exponent");
int pointPlace = FRAC_LEN-(int)exponent;
// get the whole part as the number left of the point:
long whole = mantissa >> pointPlace;
// get the frac part as the 6 first bits right of the point:
long frac = (mantissa >> (pointPlace-DENOM_LEN)) & DENOM_BITMAP;
// if the last operation shifted 1s out to the right, we lost precision, check with
// if any of these bits are set:
if((mantissa & ((MANTISSA_FRAC_BITMAP | MANTISSA_IMPLICIT_PREFIX) >> (pointPlace - DENOM_LEN))) > 0) {
System.out.println("warning: precision of input is smaller than 1/64");
}
if(frac == 0) return String.format("%d", whole);
int denom = 64;
// test last bit, divide nom and demon by 1 if not 1
while((frac & 1) == 0) {
frac = frac >> 1;
denom = denom >> 1;
}
return String.format("%d %d/%d", whole, frac, denom);
}
(this code can probably be made shorter, but reading bit-flipping-code like this is hard enough as it is...)
I create simply Fraction library.
The library is available here: https://github.com/adamjak/Fractions
Example:
String s = "1.125";
Fraction f1 = Fraction.tryParse(s);
f1.toString(); // return 9/8
Double d = 2.58;
Fraction f2 = Fraction.createFraction(d);
f2.divide(f1).toString() // return 172/75 (2.29)
To solve this problem (in one of my projects), I took the following steps:
Built a dictionary of decimal/fraction strings.
Wrote a function to search the dictionary for the closest matching fraction depending on the "decimal" part of the number and the matching criteria.