How to generate a sequence between two values in java? - java

The two values that i have are:
firstval=200.000
Secondval=399.999,
I have to generate a numbers such that when the first decimal part should get incremented till 999 for the integral part, next the integral part should be incremented and then decimal part resets to 000 and starts incrementing for the new number . And this happens till 399.
Like
200.001,200.002.....200.999,201.000,201.002....399.998,399.999"

There is a nice way to get required array with Java 8 Stream API
(1) Use double incrementation
double[] sequence = DoubleStream.iterate(200.0, d -> d + 0.001).limit((int) (1 + (399.999 - 200.0) / 0.001)).toArray();
Note, that summing up lots of doubles will likely give some error, for example on my laptop the last number in the sequence is 399.99899999686227
(2) Better way is to generate integer stream and map it to doubles:
double[] sequence = IntStream.range(200000, 400000).mapToDouble( i -> i * 0.001).toArray();
In this case no error from adding multiple doubles will be accumulated

double start = 200.0;
double end = 399.999;
double increment = 0.001;
for (double v = start; v < end + increment / 2; v += increment) {
System.out.printf("%.3f\n", v);
}

Here's another way to do it:
public static void counterGenerator(double start, double end) {
DecimalFormat counterInDecimalFormat = new DecimalFormat("0.000");
String counterInString = counterInDecimalFormat.format(start);
System.out.println(counterInString); // This is the counter in String format.
double counter = Double.parseDouble(counterInString);
if (counter < end)
counterGenerator(start + 0.001, end);
return;
}
In the above example, you have your counter in String format in the variable called counterInString
But you need not worry about the problems associated with incrementing a Double which is actual residing in a String variable. In the code, you can see the incrementing task is being done by a double counter which gets convert back to String by using the DecimalFormat class.
Here keeping your counter as a String helps you to retain the 0s after decimal in numbers like 200.000.
Hope it helps!

Related

How to convert from a double with or without a fractional part to a hexaicosadecimal string (Base-26)? [duplicate]

This question already has an answer here:
How to convert from a double without a fractional part to a hexaicosadecimal string (base-26)?
(1 answer)
Closed 1 year ago.
What is the way to convert from a double with or without a fractional part to a hexaicosadecimal string? What are some tips or possible shortcuts?
For any base B, multiply the factional decimal number part by B.
If the number is >= 1, assign to an int and convert to 0-F as appropriate.
save only the previous fraction and continue from the beginning.
Here is an example for binary.
double d = .2342;
System.out.print(".");
for (int i = 0; i < 20; i++) {
d = 2*d;
int bit = (int)d;
System.out.print(bit);
d = d-bit;
}
System.out.println();
Prints the following for .2342 with 20 bits of accuracy
.00111011111101001000
Note that since floating point products of fractions can degrade, care must be taken for long strings. And unless the fraction is a power of.5, it will be repeating.

Calculating sin function with JAVA BigDecimal -monomial is going bigger(?)

I'm making sin function with BigDecimal in JAVA, and this is as far as I go:
package taylorSeries;
import java.math.BigDecimal;
public class Sin {
private static final int cutOff = 20;
public static void main(String[] args) {
System.out.println(getSin(new BigDecimal(3.14159265358979323846264), 100));
}
public static BigDecimal getSin(BigDecimal x, int scale) {
BigDecimal sign = new BigDecimal("-1");
BigDecimal divisor = BigDecimal.ONE;
BigDecimal i = BigDecimal.ONE;
BigDecimal num = null;
BigDecimal result = x;
//System.err.println(x);
do {
x = x.abs().multiply(x.abs()).multiply(x).multiply(sign);
i = i.add(BigDecimal.ONE);
divisor = divisor.multiply(i);
i = i.add(BigDecimal.ONE);
divisor = divisor.multiply(i);
num = x.divide(divisor, scale + cutOff, BigDecimal.ROUND_HALF_UP);
result = result.add(num);
//System.out.println("d : " + divisor);
//System.out.println(divisor.compareTo(x.abs()));
System.out.println(num.setScale(9, BigDecimal.ROUND_HALF_UP));
} while(num.abs().compareTo(new BigDecimal("0.1").pow(scale + cutOff)) > 0);
System.err.println(num);
System.err.println(new BigDecimal("0.1").pow(scale + cutOff));
return result.setScale(scale, BigDecimal.ROUND_HALF_UP);
}
}
It uses Taylor series :
picture of the fomular
The monomial x is added every iteration and always negative number.
And the problem is, absolute value of x is getting bigger and bigger, so iteration never ends.
Is there and way to find them or better way to implement it from the first place?
EDIT:
I made this code from scratch with simple interest about trigonometric functions, and now I see lots of childish mistakes.
My intention first was like this:
num is x^(2k+1) / (2k+1)!
divisor is (2k+1)!
i is 2k+1
dividend is x^(2k+1)
So I update divisor and dividend with i and compute num by sign * dividend / divisor and add it to result by result = result.add(num)
so new and good-working code is:
package taylorSeries;
import java.math.BigDecimal;
import java.math.MathContext;
public class Sin {
private static final int cutOff = 20;
private static final BigDecimal PI = Pi.getPi(100);
public static void main(String[] args) {
System.out.println(getSin(Pi.getPi(100).multiply(new BigDecimal("1.5")), 100)); // Should be -1
}
public static BigDecimal getSin(final BigDecimal x, int scale) {
if (x.compareTo(PI.multiply(new BigDecimal(2))) > 0) return getSin(x.remainder(PI.multiply(new BigDecimal(2)), new MathContext(x.precision())), scale);
if (x.compareTo(PI) > 0) return getSin(x.subtract(PI), scale).multiply(new BigDecimal("-1"));
if (x.compareTo(PI.divide(new BigDecimal(2))) > 0) return getSin(PI.subtract(x), scale);
BigDecimal sign = new BigDecimal("-1");
BigDecimal divisor = BigDecimal.ONE;
BigDecimal i = BigDecimal.ONE;
BigDecimal num = null;
BigDecimal dividend = x;
BigDecimal result = dividend;
do {
dividend = dividend.multiply(x).multiply(x).multiply(sign);
i = i.add(BigDecimal.ONE);
divisor = divisor.multiply(i);
i = i.add(BigDecimal.ONE);
divisor = divisor.multiply(i);
num = dividend.divide(divisor, scale + cutOff, BigDecimal.ROUND_HALF_UP);
result = result.add(num);
} while(num.abs().compareTo(new BigDecimal("0.1").pow(scale + cutOff)) > 0);
return result.setScale(scale, BigDecimal.ROUND_HALF_UP);
}
}
The new BigDecimal(double) constructor is not something you generally want to be using; the whole reason BigDecimal exists in the first place is that double is wonky: There are almost 2^64 unique values that a double can represent, but that's it - (almost) 2^64 distinct values, smeared out logarithmically, with about a quarter of all available numbers between 0 and 1, a quarter from 1 to infinity, and the other half the same but as negative numbers. 3.14159265358979323846264 is not one of the blessed numbers. Use the string constructor instead - just toss " symbols around it.
every loop, sign should switch, well, sign. You're not doing that.
In the first loop, you overwrite x with x = x.abs().multiply(x.abs()).multiply(x).multiply(sign);, so now the 'x' value is actually -x^3, and the original x value is gone. Next loop, you repeat this process, and thus you definitely are nowhere near the desired effect. The solution - don't overwrite x. You need x, throughout the calculation. Make it final (getSin(final BigDecimal x) to help yourself.
Make another BigDecimal value and call it accumulator or what not. It starts out as a copy of x.
Every loop, you multiply x to it twice then toggle the sign. That way, the first time in the loop the accumulator is -x^3. The second time, it is x^5. The third time it is -x^7, and so on.
There is more wrong, but at some point I'm just feeding you your homework on a golden spoon.
I strongly suggest you learn to debug. Debugging is simple! All you really do, is follow along with the computer. You calculate by hand and double check that what you get (be it the result of an expression, or whether a while loop loops or not), matches what the computer gets. Check by using a debugger, or if you don't know how to do that, learn, and if you don't want to, add a ton of System.out.println statements as debugging aids. There where your expectations mismatch what the computer is doing? You found a bug. Probably one of many.
Then consider splicing parts of your code up so you can more easily check the computer's work.
For example, here, num is supposed to reflect:
before first loop: x
first loop: x - x^3/3!
second loop: x - x^3/3! + x^5/5!
etcetera. But for debugging it'd be so much simpler if you have those parts separated out. You optimally want:
first loop: 3 separated concepts: -1, x^3, and 3!.
second loop: +1, x^5, and 5!.
That debugs so much simpler.
It also leads to cleaner code, generally, so I suggest you make these separate concepts as variables, describe them, write a loop and test that they are doing what you want (e.g. you use sysouts or a debugger to actually observe the power accumulator value hopping from x to x^3 to x^5 - this is easily checked), and finally put it all together.
This is a much better way to write code than to just 'write it all, run it, realize it doesn't work, shrug, raise an eyebrow, head over to stack overflow, and pray someone's crystal ball is having a good day and they see my question'.
The fact that the terms are all negative is not the problem (though you must make it alternate to get the correct series).
The term magnitude is x^(2k+1) / (2k+1)!. The numerator is indeed growing, but so is the denominator, and past k = x, the denominator starts to "win" and the series always converges.
Anyway, you should limit yourself to small xs, otherwise the computation will be extremely lengthy, with very large products.
For the computation of the sine, always begin by reducing the argument to the range [0,π]. Even better, if you jointly develop a cosine function, you can reduce to [0,π/2].

How to print a DOUBLE with a variable INT

I'm doing my school homework and I got stuck. I set my variable as INT and now I can't change it because I'm using it for other calculations. Is there a way which I can print 3 numbers after the dot? I tried with printf and (double) but it didn't work.
This is my piece of code:
for (int i = 0; i < 2; i++) // Printing Inverse
{
System.out.print("[");
output.print("[");
for (int j = 0; j < 2; j++) {
sol[i][j] = adj[i][j] / det;
System.out.printf((double) sol[i][j] + " ");
output.print((double)sol[i][j] + " ");
}
}
By doing the calculation as a int, you are basically "throwing away" information. This means that from that point, it is not possible to get it back.
Since your current code looks like intVariable = intVariable / intVariable; print((double)intVariable), the compiler automatically uses integer division, what basically discards all decimals
You want your code to look like doubleVariable = intVariable / doubleVariable;print(doubleVariable), which would mean casting the divider in the division to a double, and changing the type of sol so it could hold doubles instead of the type you have now.
Is there a way which I can print 3 numbers after the dot? I tried with printf and (double) but it didn't work.
Well casting the int to double is not enough to get the expected output.
To print the casted double with three decimals, you need to use %3f as first parameter in the printf method, like this:
System.out.printf("%.3f", (double) sol[i][j]);
This is a live working demo.
Note:
Note that the result of the division in sol[i][j] = adj[i][j] / det; will be a double, so you need to declare your variables as double instead of int to avoid getting Exceptions.
I'm guessing that sol is a two-dimensional array of int, hence - as #B001 mentioned in his comment - it has no numbers after the decimal point. If all you want to do is print the result of the division: adj[i][j] / det as a double, I suggest using another variable just for printing the result, i.e.
double result = (double) adj[i][j] / det;
sol[i][j] = (int) result;
System.out.printf("%.3f", result);
I think you should redefine this variable again, that will not be catastrofic, just be carefull. Eclipse/NetBean will be notifying you if your variable has totally changed or not.
I am not sure, but I think that somewhere in Eclipse you could find a button that changes your variable and all its references.

How do I get the quotient of two ints to round up? (5/2)

I am having some trouble with some extra credit stuff my AP Computer Science teacher assigned. Here are the instructions:
Write a WordScrambler method recombine. This method returns a String created from its two String parameters as follows:
take the first half of word1
take the second half of word2
concatenate the two halves and return the new string
For example, the following lines show some results of calling recombine. Note that if a word has an odd number of letters, the second half of the word contains the extra letter.
here are the examples it gives:
"apple" + "pear" = "apar"
"pear" + "apple" = "peple"
it then says to create method recombine below, only giving one line of code:
private String recombine(String word1, String word2)
then I have to create the rest. I made a test program just to see if my ideas were correct, that I could use length() and substring() to do it (I know I will have to use them some time in it), then I would change the code to work with the private String recombine(word1,word2) bit. So here is my test code:
public class test
{
private static String word1,word2;
public static void main(String[]args){
word1 = "apple";
word2 = "pear";
int length1 = word1.length();
int length2 = word2.length();
System.out.println(length1);
System.out.println(length2);
int half1 = (int)Math.ceil(length1 / 2);
int half2 = length2 / 2;
System.out.println(half1);
System.out.println(half2);
}
}
the output is:
5
4
2
2
As you can see, the variable half1 should be 2.5, but since you cant use half of a letter, it should round up, but even with (int)Math.ceil it still rounds down. When I take out the int, just to see if it works as a double, it gives me an error, 'Possible loss of precision, required:int; found:double;`
The general answer to your question, for the quotient of two positive numbers a and b, is to compute(*) (a + b - 1) / b with the truncating division that most programming languages have. This produces the integer immediately above the real a / b.
In your example, b is 2. The value of length1 / 2 rounded up can be computed as (length1 + 1) / 2.
(*) This is assuming that a + b - 1 can be computed without overflow, which should not be a problem in your example.
The reason your code does not round down is that the division length1 / 2 happens before Math.ceil call, and it happens in integers.
You can round up division without using Math.ceil. For that you add a number that is less than the divisor by one to the number being divided. For example, if you want to round up the result of division by ten, add nine to the dividend:
int res = (d + 9) / 10; // Rounds up
In your case, all you need is to add one to length1:
int half1 = (length1+1) / 2;
The immediate solution is just to do the division in floating point:
int half1 = (int)Math.ceil(length1 / 2.0);
2 is an int literal and 2.0 is a double literal. Java will automatically promote length1 to double in the presence of 2.0 so this is effectively the following:
int half1 = (int)Math.ceil((double)length1 / 2.0);
But as noted by the other two answers, you don't need to use floating point. Furthermore, double only has 53 bits of integral precision so while doing the division in floating point works for an int it may result in error for a long.

String trim coming out with incorrect length

I am using Java to determine the length of a double as part of a larger program. At this time the double is 666 but the length is returning as 5, which is a big problem. I read another question posted here with a solution but that didn't work for me. I will show my code and my attempt at emulating the previous solution with results.
My original code:
double Real = 666;
int lengthTest = String.valueOf(Real).trim().length();
System.out.println("Test: " + lengthTest);
This prints 5
Modifications that didn't work, and were essentially just breaking up the code into multiple lines.
double Real = 666;
String part = Real + "";
part = part.trim();
int newLength = part.length();
System.out.println("new length : " + newLength);
This prints 5 as well.
Obviously, I want this to print how many digits I have, in this case it should show 3.
For a bigger picture if it helps I am breaking down number input into constituent parts, and making sure none of them exceed limits. ie: xx.yyezz where xx can be 5 digits, yy can be 5 digits and zz can be 2 digits. Thank you.
That's because you are using a double.
String.valueOf(Real); // returns 666.0, i.e. length 5
Try casting it to an integer first:
Integer simple = (int) Real;
String.valueOf(simple); // returns 666, i.e. length 3.
A double always puts a decimal place after the number. So the number looks like 666.0. You could see this by printing String.valueOf(Real). You should use an int instead or cast the double to an int:
double Real = 666;
int realInt = (int) Real;
System.out.println(String.valueOf(realInt).length());

Categories

Resources