Java calculate confidence interval - java

I'm looking for some method that takes or does not take parameters for calculate confidence interval.
I don't want the apache methods,
just a simple method or som type of code that does this.

My knowledge is restricted, it basically boils down to completing an online task against an expected set of answers (https://www.hackerrank.com/challenges/stat-warmup).
However, as far as I read up, there are mistakes in the given answer, and I'd like to correct these.
My source is pretty much wikipedia https://en.wikipedia.org/wiki/Confidence_interval#Basic_Steps
/**
*
* #return int[]{lower, upper}, i.e. int array with Lower and Upper Boundary of the 95% Confidence Interval for the given numbers
*/
private static double[] calculateLowerUpperConfidenceBoundary95Percent(int[] givenNumbers) {
// calculate the mean value (= average)
double sum = 0.0;
for (int num : givenNumbers) {
sum += num;
}
double mean = sum / givenNumbers.length;
// calculate standard deviation
double squaredDifferenceSum = 0.0;
for (int num : givenNumbers) {
squaredDifferenceSum += (num - mean) * (num - mean);
}
double variance = squaredDifferenceSum / givenNumbers.length;
double standardDeviation = Math.sqrt(variance);
// value for 95% confidence interval, source: https://en.wikipedia.org/wiki/Confidence_interval#Basic_Steps
double confidenceLevel = 1.96;
double temp = confidenceLevel * standardDeviation / Math.sqrt(givenNumbers.length);
return new double[]{mean - temp, mean + temp};
}

here is you go this is the code calculate Confidence Interval
/**
*
* #author alaaabuzaghleh
*/
public class TestCI {
public static void main(String[] args) {
int maximumNumber = 100000;
int num = 0;
double[] data = new double[maximumNumber];
// first pass: read in data, compute sample mean
double dataSum = 0.0;
while (num<maximumNumber) {
data[num] = num*10;
dataSum += data[num];
num++;
}
double ave = dataSum / num;
double variance1 = 0.0;
for (int i = 0; i < num; i++) {
variance1 += (data[i] - ave) * (data[i] - ave);
}
double variance = variance1 / (num - 1);
double standardDaviation= Math.sqrt(variance);
double lower = ave - 1.96 * standardDaviation;
double higher = ave + 1.96 * standardDaviation;
// print results
System.out.println("average = " + ave);
System.out.println("sample variance = " + variance);
System.out.println("sample standard daviation = " + standardDaviation);
System.out.println("approximate confidence interval");
System.out.println("[ " + lower + ", " + higher + " ]");
}
}

Related

Java: Collections.max return largest number error

Given a loop, I want to print the largest number four times. There are total_A, total_B, total_C and find the largest number among these three. But I'm facing some problems of getting the correct maximum number. The output for data training no.1 and no.4 are correct which return the largest number, but no.2 and no.3 are wrong. Below is my output:
Updated output
Below is my code:
public class Multiclass2 {
public static void main(String args []){
double x [][] = {{3.24,-0.96},
{-1.56,-0.61},
{-1.1,2.5},
{1.36,-4.8};
double [] wA = {0,1.94,3.82};
double [] wB = {0,-4.9,-4.03};
double [] wC = {0,4.48,3.25};
double threshold = 1;
int n = x.length;
double total_A = 0;
double total_B = 0;
double total_C = 0;
List<Double> li = new ArrayList<Double>();
double max = 0;
for(int i=0;i<n;i++){
System.out.println("For training data point no." + (i+1));
total_A = (threshold * wA[0]) + (x[i][0] * wA[1]) + (x[i][1] * wA[2]);
total_B = (threshold * wB[0]) + (x[i][0] * wB[1]) + (x[i][1] * wB[2]);
total_C = (threshold * wC[0]) + (x[i][0] * wC[1]) + (x[i][1] * wC[2]);
li.add(total_A);
li.add(total_B);
li.add(total_C);
max = Collections.max(li);
System.out.println(total_A+", "+total_B+", "+total_C);
System.out.println("MAx is "+max);
}
}
}
You're using the same collection accross the entire loop, so you're calculating the max of ALL data points. You made two code style mistakes which allowed this bug to happen:
firstly, you did not choose the appropriate scope for your variables. Since they're local to the loop, they should be declared inside the loop, not outside
secondly, constructing a collection for calculating the max of a fixed, small number of numbers is overkill. Just use Math.max(a, Math.max(b, c))
The corrected code would be:
public static void main(String args[]) {
double x[][] = {
{ 3.24, -0.96 },
{ -1.56, -0.61 },
{ -1.1, 2.5 },
{ 1.36, -4.8 }
};
double[] wA = { 0, 1.94, 3.82 };
double[] wB = { 0, -4.9, -4.03 };
double[] wC = { 0, 4.48, 3.25 };
double threshold = 1;
int n = x.length;
for (int i = 0; i < n; i++) {
System.out.println("For training data point no." + (i + 1));
double total_A = (threshold * wA[0]) + (x[i][0] * wA[1]) + (x[i][1] * wA[2]);
double total_B = (threshold * wB[0]) + (x[i][0] * wB[1]) + (x[i][1] * wB[2]);
double total_C = (threshold * wC[0]) + (x[i][0] * wC[1]) + (x[i][1] * wC[2]);
double max = Math.max(total_A, Math.max(total_B, total_C));
System.out.println(total_A + ", " + total_B + ", " + total_C);
System.out.println("Max is " + max);
}
}

java Sine(x) Taylor Series

Can someone help me for geting out this code of sin(x) Tailor function to get followings:
The first 4 sin(x) Tailor series.
To calculating the sin function using the sum-formel
How to write a method public static double MySinApproximate( double x)?
That is what i get so far, and it has to be in this way!!
import java.lang.Math;
public class mysin {
public static void main(String[] args){
double x= Math.PI;
System.out.println( MySin(x) + "\t \t" + Math.sin(x) + "\n" );
}
public static double MySin(double x){
double sumNeu, sumOld, sum;
int i = 1;
sum = sumNeu = x; // This should calculating the first term Value
do //the loop do will calculating the Tailor Series
{
sumOld = sumNeu;
i++; sum = + sum * x * x / i;
i++; sum = sum / i;
sumNeu = sumOld + sum;
}
while( sumNeu != sumOld);
return sumNeu;
}
} // 11.548739357257745 1.2246467991473532E-16 (as output)
Your loop isn't calculating the Taylor series correctly. (This is really a Maclaurin series, which is the special case of a Taylor series with a = 0.) For the sine function, the terms need to be added and subtracted in an alternating fashion.
sin(x) = x - x3/3! + x5/5! - ...
Your method only adds the terms.
sin(x) = x + x3/3! + x5/5! + ...
Flip the sign of sum on each iteration, by adding the designated line:
do // The loop will calculate the Taylor Series
{
sumOld = sumNeu;
i++; sum = + sum * x * x / i;
i++; sum = sum / i;
sum = -sum; // Add this line!
sumNeu = sumOld + sum;
}
With this change I get a result that is very close:
2.3489882528577605E-16 1.2246467991473532E-16
Due to the inherent inaccuracies of floating-point math in Java (and IEEE in general), this is likely as close as you'll get by writing your own sine method.
I tested an additional case of π/2:
System.out.println( MySin(x/2) + "\t \t" + Math.sin(x/2) + "\n" );
Again, it's close:
1.0000000000000002 1.0
1.I want to write all again like that -
2.I try to writing the first 4 series from sine Taylor and the proximity all together but anyhow doesn't work correctly -
3.i get this output
0.0 0.8414709848078965
0.8414709848078965 0.9092974268256817
0.8414709848078965 0.1411200080598672
0.9092974268256817 -0.7568024953079282
4.How can i get the same accuracy
1.0000000000000002 1.0
and the series of sine(x)?
public class MySin {
public static void main(String[] args){
double y = 0;
y = 4;
for (int i = 1; i<= y; i++){
System.out.println( MySin(i/2) + "\t \t" + Math.sin(i) + "\n" );
}
}
public static double MySin(double x){
double sumNew, sumOld, sum;
int i = 1;
sum = sumNew = x; // This should calculating the first term Value
do //the loop do will calculating the Tailor Series
{
sumOld = sumNew;
i++; sum = - sum * x * x / i; // i did change the sign to -
i++; sum = sum / i;
sum = - sum; // so i don't need this line anymore
sumNew = sumOld + sum;
}
while( sumNew != sumOld);
return sumNew;
}
public static double MySineProximity ( double x) {
while ( x <= ( Math.PI /2 ) )
{
x = 0;
}
return MySin (x);
}
}

Riemann Zeta Function in Java - Infinite Recursion with Functional Form

Note: Updated on 06/17/2015. Of course this is possible. See the solution below.
Even if anyone copies and pastes this code, you still have a lot of cleanup to do. Also note that you will have problems inside the critical strip from Re(s) = 0 to Re(s) = 1 :). But this is a good start.
import java.util.Scanner;
public class NewTest{
public static void main(String[] args) {
RiemannZetaMain func = new RiemannZetaMain();
double s = 0;
double start, stop, totalTime;
Scanner scan = new Scanner(System.in);
System.out.print("Enter the value of s inside the Riemann Zeta Function: ");
try {
s = scan.nextDouble();
}
catch (Exception e) {
System.out.println("You must enter a positive integer greater than 1.");
}
start = System.currentTimeMillis();
if (s <= 0)
System.out.println("Value for the Zeta Function = " + riemannFuncForm(s));
else if (s == 1)
System.out.println("The zeta funxtion is undefined for Re(s) = 1.");
else if(s >= 2)
System.out.println("Value for the Zeta Function = " + getStandardSum(s));
else
System.out.println("Value for the Zeta Function = " + getNewSum(s));
stop = System.currentTimeMillis();
totalTime = (double) (stop-start) / 1000.0;
System.out.println("Total time taken is " + totalTime + " seconds.");
}
// Standard form the the Zeta function.
public static double standardZeta(double s) {
int n = 1;
double currentSum = 0;
double relativeError = 1;
double error = 0.000001;
double remainder;
while (relativeError > error) {
currentSum = Math.pow(n, -s) + currentSum;
remainder = 1 / ((s-1)* Math.pow(n, (s-1)));
relativeError = remainder / currentSum;
n++;
}
System.out.println("The number of terms summed was " + n + ".");
return currentSum;
}
public static double getStandardSum(double s){
return standardZeta(s);
}
//New Form
// zeta(s) = 2^(-1+2 s)/((-2+2^s) Gamma(1+s)) integral_0^infinity t^s sech^2(t) dt for Re(s)>-1
public static double Integrate(double start, double end) {
double currentIntegralValue = 0;
double dx = 0.0001d; // The size of delta x in the approximation
double x = start; // A = starting point of integration, B = ending point of integration.
// Ending conditions for the while loop
// Condition #1: The value of b - x(i) is less than delta(x).
// This would throw an out of bounds exception.
// Condition #2: The value of b - x(i) is greater than 0 (Since you start at A and split the integral
// up into "infinitesimally small" chunks up until you reach delta(x)*n.
while (Math.abs(end - x) >= dx && (end - x) > 0) {
currentIntegralValue += function(x) * dx; // Use the (Riemann) rectangle sums at xi to compute width * height
x += dx; // Add these sums together
}
return currentIntegralValue;
}
private static double function(double s) {
double sech = 1 / Math.cosh(s); // Hyperbolic cosecant
double squared = Math.pow(sech, 2);
return ((Math.pow(s, 0.5)) * squared);
}
public static double getNewSum(double s){
double constant = Math.pow(2, (2*s)-1) / (((Math.pow(2, s)) -2)*(gamma(1+s)));
return constant*Integrate(0, 1000);
}
// Gamma Function - Lanczos approximation
public static double gamma(double s){
double[] p = {0.99999999999980993, 676.5203681218851, -1259.1392167224028,
771.32342877765313, -176.61502916214059, 12.507343278686905,
-0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7};
int g = 7;
if(s < 0.5) return Math.PI / (Math.sin(Math.PI * s)*gamma(1-s));
s -= 1;
double a = p[0];
double t = s+g+0.5;
for(int i = 1; i < p.length; i++){
a += p[i]/(s+i);
}
return Math.sqrt(2*Math.PI)*Math.pow(t, s+0.5)*Math.exp(-t)*a;
}
//Binomial Co-efficient - NOT CURRENTLY USING
/*
public static double binomial(int n, int k)
{
if (k>n-k)
k=n-k;
long b=1;
for (int i=1, m=n; i<=k; i++, m--)
b=b*m/i;
return b;
} */
// Riemann's Functional Equation
// Tried this initially and utterly failed.
public static double riemannFuncForm(double s) {
double term = Math.pow(2, s)*Math.pow(Math.PI, s-1)*(Math.sin((Math.PI*s)/2))*gamma(1-s);
double nextTerm = Math.pow(2, (1-s))*Math.pow(Math.PI, (1-s)-1)*(Math.sin((Math.PI*(1-s))/2))*gamma(1-(1-s));
double error = Math.abs(term - nextTerm);
if(s == 1.0)
return 0;
else
return Math.pow(2, s)*Math.pow(Math.PI, s-1)*(Math.sin((Math.PI*s)/2))*gamma(1-s)*standardZeta(1-s);
}
}
Ok well we've figured out that for this particular function, since this form of it isn't actually a infinite series, we cannot approximate using recursion. However the infinite sum of the Riemann Zeta series (1\(n^s) where n = 1 to infinity) could be solved through this method.
Additionally this method could be used to find any infinite series' sum, product, or limit.
If you execute the code your currently have, you'll get infinite recursion as 1-(1-s) = s (e.g. 1-s = t, 1-t = s so you'll just switch back and forth between two values of s infinitely).
Below I talk about the sum of series. It appears you are calculating the product of the series instead. The concepts below should work for either.
Besides this, the Riemann Zeta Function is an infinite series. This means that it only has a limit, and will never reach a true sum (in finite time) and so you cannot get an exact answer through recursion.
However, if you introduce a "threshold" factor, you can get an approximation that is as good as you like. The sum will increase/decrease as each term is added. Once the sum stabilizes, you can quit out of recursion and return your approximate sum. "Stabilized" is defined using your threshold factor. Once the sum varies by an amount less than this threshold factor (which you have defined), your sum has stabilized.
A smaller threshold leads to a better approximation, but also longer computation time.
(Note: this method only works if your series converges, if it has a chance of not converging, you might also want to build in a maxSteps variable to cease execution if the series hasn't converged to your satisfaction after maxSteps steps of recursion.)
Here's an example implementation, note that you'll have to play with threshold and maxSteps to determine appropriate values:
/* Riemann's Functional Equation
* threshold - if two terms differ by less than this absolute amount, return
* currSteps/maxSteps - if currSteps becomes maxSteps, give up on convergence and return
* currVal - the current product, used to determine threshold case (start at 1)
*/
public static double riemannFuncForm(double s, double threshold, int currSteps, int maxSteps, double currVal) {
double nextVal = currVal*(Math.pow(2, s)*Math.pow(Math.PI, s-1)*(Math.sin((Math.PI*s)/2))*gamma(1-s)); //currVal*term
if( s == 1.0)
return 0;
else if ( s == 0.0)
return -0.5;
else if (Math.abs(currVal-nextVal) < threshold) //When a term will change the current answer by less than threshold
return nextVal; //Could also do currVal here (shouldn't matter much as they differ by < threshold)
else if (currSteps == maxSteps)//When you've taken the max allowed steps
return nextVal; //You might want to print something here so you know you didn't converge
else //Otherwise just keep recursing
return riemannFuncForm(1-s, threshold, ++currSteps, maxSteps, nextVal);
}
}
This is not possible.
The functional form of the Riemann Zeta Function is --
zeta(s) = 2^s pi^(-1+s) Gamma(1-s) sin((pi s)/2) zeta(1-s)
This is different from the standard equation in which an infinite sum is measured from 1/k^s for all k = 1 to k = infinity. It is possible to write this as something similar to --
// Standard form the the Zeta function.
public static double standardZeta(double s) {
int n = 1;
double currentSum = 0;
double relativeError = 1;
double error = 0.000001;
double remainder;
while (relativeError > error) {
currentSum = Math.pow(n, -s) + currentSum;
remainder = 1 / ((s-1)* Math.pow(n, (s-1)));
relativeError = remainder / currentSum;
n++;
}
System.out.println("The number of terms summed was " + n + ".");
return currentSum;
}
The same logic doesn't apply to the functional equation (it isn't a direct sum, it is a mathematical relationship). This would require a rather clever way of designing a program to calculate negative values of Zeta(s)!
The literal interpretation of this Java code is ---
// Riemann's Functional Equation
public static double riemannFuncForm(double s) {
double currentVal = (Math.pow(2, s)*Math.pow(Math.PI, s-1)*(Math.sin((Math.PI*s)/2))*gamma(1-s));
if( s == 1.0)
return 0;
else if ( s == 0.0)
return -0.5;
else
System.out.println("Value of next value is " + nextVal(1-s));
return currentVal;//*nextVal(1-s);
}
public static double nextVal(double s)
{
return (Math.pow(2, s)*Math.pow(Math.PI, s-1)*(Math.sin((Math.PI*s)/2))*gamma(1-s));
}
public static double getRiemannSum(double s) {
return riemannFuncForm(s);
}
Testing on three or four values shows that this doesn't work. If you write something similar to --
// Riemann's Functional Equation
public static double riemannFuncForm(double s) {
double currentVal = Math.pow(2, s)*Math.pow(Math.PI, s-1)*(Math.sin((Math.PI*s)/2))*gamma(1-s); //currVal*term
if( s == 1.0)
return 0;
else if ( s == 0.0)
return -0.5;
else //Otherwise just keep recursing
return currentVal * nextVal(1-s);
}
public static double nextVal(double s)
{
return (Math.pow(2, s)*Math.pow(Math.PI, s-1)*(Math.sin((Math.PI*s)/2))*gamma(1-s));
}
I was misinterpretation how to do this through mathematics. I will have to use a different approximation of the zeta function for values less than 2.
I think I need to use a different form of the zeta function. When I run the entire program ---
import java.util.Scanner;
public class Test4{
public static void main(String[] args) {
RiemannZetaMain func = new RiemannZetaMain();
double s = 0;
double start, stop, totalTime;
Scanner scan = new Scanner(System.in);
System.out.print("Enter the value of s inside the Riemann Zeta Function: ");
try {
s = scan.nextDouble();
}
catch (Exception e) {
System.out.println("You must enter a positive integer greater than 1.");
}
start = System.currentTimeMillis();
if(s >= 2)
System.out.println("Value for the Zeta Function = " + getStandardSum(s));
else
System.out.println("Value for the Zeta Function = " + getRiemannSum(s));
stop = System.currentTimeMillis();
totalTime = (double) (stop-start) / 1000.0;
System.out.println("Total time taken is " + totalTime + " seconds.");
}
// Standard form the the Zeta function.
public static double standardZeta(double s) {
int n = 1;
double currentSum = 0;
double relativeError = 1;
double error = 0.000001;
double remainder;
while (relativeError > error) {
currentSum = Math.pow(n, -s) + currentSum;
remainder = 1 / ((s-1)* Math.pow(n, (s-1)));
relativeError = remainder / currentSum;
n++;
}
System.out.println("The number of terms summed was " + n + ".");
return currentSum;
}
public static double getStandardSum(double s){
return standardZeta(s);
}
// Riemann's Functional Equation
public static double riemannFuncForm(double s, double threshold, double currSteps, int maxSteps) {
double term = Math.pow(2, s)*Math.pow(Math.PI, s-1)*(Math.sin((Math.PI*s)/2))*gamma(1-s);
//double nextTerm = Math.pow(2, (1-s))*Math.pow(Math.PI, (1-s)-1)*(Math.sin((Math.PI*(1-s))/2))*gamma(1-(1-s));
//double error = Math.abs(term - nextTerm);
if(s == 1.0)
return 0;
else if (s == 0.0)
return -0.5;
else if (term < threshold) {//The recursion will stop once the term is less than the threshold
System.out.println("The number of steps is " + currSteps);
return term;
}
else if (currSteps == maxSteps) {//The recursion will stop if you meet the max steps
System.out.println("The series did not converge.");
return term;
}
else //Otherwise just keep recursing
return term*riemannFuncForm(1-s, threshold, ++currSteps, maxSteps);
}
public static double getRiemannSum(double s) {
double threshold = 0.00001;
double currSteps = 1;
int maxSteps = 1000;
return riemannFuncForm(s, threshold, currSteps, maxSteps);
}
// Gamma Function - Lanczos approximation
public static double gamma(double s){
double[] p = {0.99999999999980993, 676.5203681218851, -1259.1392167224028,
771.32342877765313, -176.61502916214059, 12.507343278686905,
-0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7};
int g = 7;
if(s < 0.5) return Math.PI / (Math.sin(Math.PI * s)*gamma(1-s));
s -= 1;
double a = p[0];
double t = s+g+0.5;
for(int i = 1; i < p.length; i++){
a += p[i]/(s+i);
}
return Math.sqrt(2*Math.PI)*Math.pow(t, s+0.5)*Math.exp(-t)*a;
}
//Binomial Co-efficient
public static double binomial(int n, int k)
{
if (k>n-k)
k=n-k;
long b=1;
for (int i=1, m=n; i<=k; i++, m--)
b=b*m/i;
return b;
}
}
I notice that plugging in zeta(-1) returns -
Enter the value of s inside the Riemann Zeta Function: -1
The number of steps is 1.0
Value for the Zeta Function = -0.0506605918211689
Total time taken is 0.0 seconds.
I knew that this value was -1/12. I checked some other values with wolfram alpha and observed that --
double term = Math.pow(2, s)*Math.pow(Math.PI, s-1)*(Math.sin((Math.PI*s)/2))*gamma(1-s);
Returns the correct value. It is just that I am multiplying this value every time by zeta(1-s). In the case of Zeta(1/2), this will always multiply the result by 0.99999999.
Enter the value of s inside the Riemann Zeta Function: 0.5
The series did not converge.
Value for the Zeta Function = 0.999999999999889
Total time taken is 0.006 seconds.
I am going to see if I can replace the part for --
else if (term < threshold) {//The recursion will stop once the term is less than the threshold
System.out.println("The number of steps is " + currSteps);
return term;
}
This difference is the error between two terms in the summation. I may not be thinking about this correctly, it is 1:16am right now. Let me see if I can think better tomorrow ....

What's with this output from a double? [duplicate]

This question already has answers here:
Java: Inaccuracy using double [duplicate]
(4 answers)
Closed 9 years ago.
I am getting strange output when I add doubles together. Can someone tell me why I'm getting repeating decimals when I am adding 0.1 every time?
I have worked out the formula for adding these numbers together and I have done this myself on paper up to 3.3... The sum of all numbers (decreasing by 1 tenth) from 3.3 to 1 equals 51.6
3.3
3.2
3.1 +
3.0
...
1.0
_
51.6
There is an easier way to calculate this using two formulas:
The linear formula for the increasing number: Y = 0.1X + 1
And the sum of increasing numbers formula: [X * (Y + 1)]/2 = total
first solve for Y using any number (in this case 100)
11 = 0.1(100) + 1
Then solve for the total using X and Y
[100 * (11+1)]/2 = 600
The output of the following code should be 600 I believe. There is no question that it should not have a repeating decimal. What am I doing wrong here? There must be something I missed.
public static void main(String[] args) {
int days = 100;
double inc = 0.1;
double init = 1;
double total = 0;
for (int i = 1; i <= days; i++) {
if (i == 1) {
total = total + init;
} else {
init = init + inc;
total = total + init;
}
}
System.out.println("Total: " + total);
System.out.println("Daily: " + init);
}
Double does not have infinite precision (Neither does BigDecimal, but BigDecimal has sufficient precision for this implementation).
Try this,
public static void main(String[] args) {
int days = 100;
java.math.BigDecimal init = java.math.BigDecimal.ONE;
java.math.BigDecimal total = java.math.BigDecimal.ZERO;
java.math.BigDecimal oneTenth = new java.math.BigDecimal(
"0.1");
for (int i = 1; i <= days; i++) {
if (i != 1) {
init = init.add(oneTenth);
}
total = total.add(init);
}
System.out.println("Total: " + total);
System.out.println("Daily: " + init);
}
Which outputs
Total: 595.0
Daily: 10.9
Please read the link that Don Roby posted. In essence, double precision is not a good way to represent fractions. A number like 0.1 does not have an exact representation in binary float notation - because floating point numbers are written as "something times two to the power something else". And you cannot solve that exactly for 0.1. Thus, you are really getting a slightly smaller number - actually
0.0999999999999998
And that missing amount is enough to mess up the math…
See Jon Skeet's very excellent answer on this topic: https://stackoverflow.com/a/1089026/1967396
The formula should be
0.1 * (100 * (100 + 1) / 2)
except you start at 10 * 0.1 so the formula is more complicated.
In any case double precision is not exact esp for numbers like 0.1, so you should expect to get rounding error.
You can work around this by using numbers which can be represented accurately like 1 instead of 0.1 (or rounding the result)
public static void main(String... ignored) {
int days = 100;
double inc = 1;
double init = 10;
double total = 0;
for (int i = 1; i <= days; i++) {
if (i == 1) {
total = total + init;
} else {
init = init + inc;
total = total + init;
}
}
total /= 10;
init /= 10;
System.out.println("Total: " + total);
System.out.println("Daily: " + init);
}
or round the result.
public static void main(String... ignored) {
int days = 100;
double inc = 0.1;
double init = 1;
double total = 0;
for (int i = 1; i <= days; i++) {
if (i == 1) {
total = total + init;
} else {
init = init + inc;
total = total + init;
}
}
System.out.printf("Total: %.1f%n", total);
System.out.printf("Daily: %.1f%n", init);
}
both print
Total: 595.0
Daily: 10.9

help for a java assignment

I have created a method to create some random double values for example 10 values : num1, num2, …num10 which sum of this 10 values is 1 : num1+num2+…+num10 = 1
My method is like the method in forum
Getting N random numbers that the sum is M :
private static double[] randSum(int n, double m) {
Random rand = new Random();
double randNums[] = new double[n], sum = 0;
for (int i = 0; i < randNums.length; i++) {
randNums[i] = rand.nextDouble();
sum += randNums[i];
}
for (int i = 0; i < randNums.length; i++) {
randNums[i] /= sum * m;
}
return randNums;
}
But this method create very long numbers like: 0.18593711849349975
I even used Math.round() method but with this method my numbers are 0.0, 0.5, 0.0 , …
I need numbers from 0.01 to 0.99 or 0.1 to 0.9. If I was using integer numbers I could do this with something like Random.nextInt(0.98) +0.01 , but nextDouble() method doesn’t accept parameters, how can I do this? Would you please help me? thanks
You could generate integers via nextInt, and then divide them by the required power of 10.
Generate nextDouble(); and round it using this method
public static double round(double d, int decimalPlace){
BigDecimal bd = new BigDecimal(Double.toString(d));
bd = bd.setScale(decimalPlace,BigDecimal.ROUND_HALF_UP);
return bd.doubleValue();
}
double d = 3.1537;
// output is 3.2
System.out.println(d + " : " + round(d, 1));
// output is 3.15
System.out.println(d + " : " + round(d, 2));
// output is 3.154
System.out.println(d + " : " + round(d, 3));
Source
Multiply your number by 100 and round the result. That will give you the original number with the insignificant digits stripped off. Then subsequently divide the result by 100 to get back to the original scale.
x = Math.round(x*100.0) / 100.0;
If you want to use 2 decimals, you could do it as follows:
private static double[] randSum(int n, double m){
double[] randoms = new double[n];
int valueLeft = (int) (m * 100);
for(int i = 0; i < n-1; i++){
int tempRand = (int)(Math.random() * valueLeft);
randoms[i] = (double)tempRand / 100;
valueLeft -= tempRand;
System.out.println(tempRand + " " + randoms[i] + " " + valueLeft);
}
randoms[n-1] = (double)valueLeft/100;
return randoms;
}

Categories