This question already has answers here:
Double division behaving wrongly
(4 answers)
Closed 7 years ago.
I have been trying for a few days to compute pi using the series expansion pi = 4(1-1/3+1/5-1/7... but whenever I use the code I have below, it returns 4.0.
public class Pi {
public static void main (String args[]) {
double pie = 0.0;
int max = 1000;
for (int x = 1 ; x < max ; x = x + 2) {
if (x % 4 == 1) {
pie+= 1/x;
} else if (x % 4 == 3) {
pie-=1/x;
}
}
System.out.println(4*pie);
}
}
In this, I am computing pie to a denominator below 1000. Pie is the variable that stores my value created for pie. At the end, it prints pi, but always returns 4.0.
Using the Debug feature in my IDE (Eclipse), I see the value of pie jumps to 4 from the initial value of 0, but then does not change for the rest of the times the program increments the value of x in the for loop, it does not do anything to pi.
You are performing integer division with 1/x, which always results in an int, truncating the true decimal value. 1/1 is 1, but 1 divided by anything larger is 0 in Java, so your result will always be 4.
Use a double literal to force floating-point division.
pie += 1.0 / x; // and pie -= 1.0 / x;
Alternatively, you can cast 1 to a double.
pie += (double) 1 / x; // and pie -= (double) 1 / x;
The problem is that you are performing integer division and adding the result to a double. x is an int and 1 is an int. When you divide an integer by an integer, you get back an integer. Hence what you're adding to pie is always an integer.
The first time you run the loop, you evaluate the expression 1/1, which returns just 1 (an integer) and assigns that value to pie. For everything else after, you get 0, which means that pie doesn't change. Hence when you finally print 4 * pie, you get 4.
There are a few options:
Use double everywhere.
Change pie += 1 / x; to pie += (1.0 / x); (and the same for the other one)
Cast 1 to double before adding to pie: pie += (double) 1 / x.
The problem is that you are making an integer division which returns less than zero. As an integer, the value will be rounded to zero instead. This adds zero to pie on each iteration.
What you need to do is to replace the literal integer ones, to literal floating point ones, like this
package cl.misc.pi;
public class Pi {
public static void main(String args[]) {
double pie = 0.0;
int max = 1000;
for (int x = 1; x < max; x = x + 2) {
if (x % 4 == 1) {
pie += 1.00 / x;
} else if (x % 4 == 3) {
pie -= 1.00 / x;
}
}
System.out.println(4 * pie);
}
}
As you see, I did replace pie += 1 / x for pie += 1.00 / x which now adds a floating point result to pie.
Result of this routine is 3.139592655589785
Related
I'm trying to write a program that can multiply all the digits of a number from 0 to 1000 exclusive using only math expressions in Java. My program works fine as long as the user types in a 3-digit number, but results in 0 if they type in anything less than 100.
I have tried getting the last digit of the input with '%10' and removing the last digit with '/10' but without a control statement to detect if the input has been reduced to zero, the program ends up multiplying by 0 when a 2-digit number has been reduced to zero, giving an incorrect result.
public class MultiplyDigits {
public static void main(String[] args){
java.util.Scanner input = new java.util.Scanner(System.in);
System.out.print("Enter a number between 0 and 1000: ");
int number = input.nextInt();
int product = 1;
product*=number%10;
number/=10;
product*=number%10;
number/=10;
product*=number%10;
System.out.println(product);
}
}
An input of 55 should result in 25, but my program does 5 x 5 x 0 = 0
An input of 999 results in 729, which is correct. 9 x 9 x 9 = 729
Some more clarification, this is a problem out of the 2nd chapter of a textbook for complete novices. The author has not covered selection statements, loops, writing our own methods or classes, or anything more advanced than elementary programming, so the implication is that this is doable without those. The book has covered invoking methods in classes built into Java, although the author has only mentioned methods in the Math and System classes. For example, Math.max(), Math.min(), Math.pow(), System.currentTimeMillis();
What about this variant. To find the first number, you can decrease, first of all, the entered number by 100 and add 1 to avoid 0 during multipication. And , as recomended NVioli, the second number should be the same updated to have a possibility to enter number lower then 10. Thus, the final variant is:
int number = input.nextInt();
int t1 = 1 + (number-100) / 100;
int t2 = (1 + (number-10) / 10) % 10; \\By NVioli
int t3 = number % 10;
int product = t1 * t2 * t3;
System.out.println(product);
The first part is to extract the essential code into a separate Java method. I'm calling it dprod, which is short for "digit product".
static int dprod(int x) {
int hun = x / 100 % 10;
int ten = x / 10 % 10;
int one = x / 1 % 10;
return hun * ten * one;
}
The above code is the naive version that only works for numbers >= 100.
To treat numbers less than 100 as expected, you need to replace the hun or ten with 1 if it is 0.
static int dprod(int x) {
int hun = x < 100 ? 1 : x / 100 % 10;
int ten = x < 10 ? 1 : x / 10 % 10;
int one = x / 1 % 10;
return hun * ten * one;
}
The ?: operator is called a conditional operator, therefore it is probably not allowed under your rules. There is a possible workaround by using the ?: operator without writing it explicitly, by using the Math.max function.
static int dprod(int x) {
int hun = Math.max(100, x) / 100 % 10;
int ten = Math.max(10, x) / 10 % 10;
int one = x / 1 % 10;
return hun * ten * one;
}
The Math.max function uses the ?: operator internally, therefore it might be forbidden, too. This is subject to discussion though, since it depends on the exact wording of the rules and their intention.
If Math.max is forbidden, it is possible to implement it entirely without branches or conditions, see this C++ question, which can be translated to Java by replacing int32 with int and by replacing inline with static.
The complete code, including automatic tests, is:
package de.roland_illig.so;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.Test;
public class DprodTest {
static int dprod(int x) {
int hun = Math.max(x, 100) / 100 % 10;
int ten = Math.max(x, 10) / 10 % 10;
int one = x / 1 % 10;
return hun * ten * one;
}
#Test
public void testDprod() {
assertThat(dprod(999)).isEqualTo(729);
assertThat(dprod(123)).isEqualTo(6);
assertThat(dprod(99)).isEqualTo(81);
assertThat(dprod(9)).isEqualTo(9);
}
}
You could just initialize the program with a length 1000 array, initialize it with the value of each number, and then your real problem simplifies to:
System.out.println(calculatedArray[number]);
Your initialization could even take advantage of the fact that a leading 0 doesn't matter according to your rules (55 and 155 are the same result.)
calculatedArray[55] = calculcate(155);
there are some ways which can help you but all of them has a simple loop or if:
You can use digits = Logarithm of your number(10 base) and then you have number of digits, then you can use a loop to calculate the result. your loop will be repeated digit times so no matter how many digits your number has, it will always work.
You can check if your number is less than 100 and then just add 100 to that, then calculate the result, because of 1 * digit1 * digit2 there will be no error.
Background:
I've successfully written code that generates a sine wave from 0 to 2pi. Adjusting the constants xPrecision and yPrecision, you can stretch the graph horizontally or vertically.
I gain this neat output (in Eclipse), when xPrecision = yPrecision = 10:
My query:
I now wish to display digits 0 to 9 instead of the stars. So, the leftmost star is replaced by 0, the second left-most star is replaced by 1, and so on. When you reach 9, the next digit is again zero.
I am clueless as to how to do this. I have looked at wave patterns like this, but they are fixed width patterns, while mine is scalable.
The only way I can think of is converting my output to a 2D character array, then scraping the *s manually from left to right, and replacing them with the digits, and then printing it. However, this is extremely memory consuming at bigger values of x/yPrecision.
What is the most optimized way to achieve this output?
Code to print sine wave:
class sine {
static final double xPrecision = 10.0; // (1/xPrecision) is the precision on x-values
static final double yPrecision = 10.0; // (1/yPrecision) is the precision on y-values
static final int PI = (int) (3.1415 * xPrecision);
static final int TPI = 2 * PI; // twice PI
static final int HPI = PI / 2; // half PI
public static void main(String[] args) {
double xd;
for(int start = (int) (1 * yPrecision), y = start; y >= -start; y--){
double x0 = Math.asin(y / yPrecision),
x1 = bringXValueWithinPrecision(x0),
x2 = bringXValueWithinPrecision(x0 + TPI / xPrecision),
x3 = bringXValueWithinPrecision(PI/xPrecision - x0);
// for debug
//System.out.println(y + " " + x0 + " " + x1 + " " + x2 + " " + x3);
for(int x = 0; x <= TPI; x++){
xd = (x / xPrecision);
if(x1 == xd || x2 == xd || x3 == xd)
System.out.print("*");
else System.out.print(" ");
}
System.out.println();
}
}
public static double bringXValueWithinPrecision(double num){
// obviously num has 16 floating points
// we need to get num within our precision
return Math.round(num * xPrecision) / xPrecision;
}
}
"Draw" the graph in memory first, then assign digits to its vertical points, and print them in a separate pass.
01
9 2
8 3
7 4
6 5
5 6
4 7
3 8
2 9
1 0
0 1 2
2 1
3 0
4 9
5 8
6 7
7 6
8 5
9 4
0 3
12
See comments in the code for an explanation of how this works:
static final double xPrecision = 10.0; // (1/xPrecision) is the precision on x-values
static final double yPrecision = 10.0; // (1/yPrecision) is the precision on y-values
static final int PI = (int) (3.1415 * xPrecision);
static final int TPI = 2 * PI; // twice PI
static final int HPI = PI / 2; // half PI
public static void main(String[] args) {
// This part is the same as OP's code, except that instead of printing '*'
// it stores the corresponding row number in the array of rows
double xd;
int[] row = new int[100];
Arrays.fill(row, -1);
int r = 0;
int maxc = 0; // Mark the rightmost column of all iterations
for(int start = (int) (1 * yPrecision), y = start; y >= -start; y--){
double x0 = Math.asin(y / yPrecision),
x1 = bringXValueWithinPrecision(x0),
x2 = bringXValueWithinPrecision(x0 + TPI / xPrecision),
x3 = bringXValueWithinPrecision(PI/xPrecision - x0);
int c = 0;
for(int x = 0; x <= TPI; x++, c++){
xd = (x / xPrecision);
// This is where the asterisk used to go
if(x1 == xd || x2 == xd || x3 == xd)
row[c] = r;
}
maxc = Math.max(c, maxc);
r++;
}
// Walk the assigned rows, and give each one a consecutive digit
int[] digit = new int[100];
int current = 0;
for (int i = 0 ; i != 100 ; i++) {
if (row[i] != -1) {
digit[i] = (current++) % 10;
}
}
// Now walk the rows again, this time printing the pre-assigned digits
for (int i = 0 ; i != r ; i++) {
for (int c = 0 ; c != maxc ; c++) {
if (row[c] == i) {
System.out.print(digit[c]);
} else {
System.out.print(' ');
}
}
System.out.println();
}
}
public static double bringXValueWithinPrecision(double num){
// obviously num has 16 floating points
// we need to get num within our precision
return Math.round(num * xPrecision) / xPrecision;
}
The first part of the code fills row[i] array, which contains row for the asterisk in column i. First few numbers from row[] array would look like this:
10 9 8 7 6 5 4 - 3 2 - 1 - - - 0 0 - - - 1 - 2 3 - 4 5 6 7 8 9 10
- denotes cells with -1, which represents a missing value. The array says that the left-most asterisk is on row 10, the next asterisk is on row 9, then 8, 7, 6, and so on. Asterisks 11 and 12 are on row zero, which is at the top.
The second loop walks rows, skips -1s, and assign consecutive digits to all non-negative positions.
The third loop walks the entire field again going row-by-row, printing values from pre-assigned digit[] array when the current row matches the value in the row[] array.
Demo.
If you replace:
System.out.print("*");
with
System.out.print(""+(x%10));
it seems to nearly work.
56
1 0
9 2
8 3
6 5
5 6
4 7
3 8
2 9
1 0
0 1 2
2 1
3 0
4 9
5 8
6 7
7 6
9 4
0 3
2 1
67
Perhaps some further adjustments might get it perfect.
Doing it in a completely different way produces a different picture but achieves your effect.
Essentially,
for each y
for each x
calculate fx = sin(x)
if fx == y print * else print space
It's very inefficient as it calculates sin(x) x*y times when, if you filled a matrix, you could calculate sin(x) just x times.
static final double xPrecision = 10.0; // (1/xPrecision) is the precision on x-values
static final double yPrecision = 10.0; // (1/yPrecision) is the precision on y-values
private void sine() {
for (double y = 1; y >= -1; y -= 1.0 / yPrecision) {
int n = 0;
for (double x = 0; x < 2.0 * Math.PI; x += 1.0 / xPrecision, n++) {
double fx = Math.sin(x);
boolean star = Math.round(fx*xPrecision) == Math.round(y*yPrecision);
System.out.print((star ? ""+(n%10) : " "));
}
System.out.println();
}
}
public void test(String[] args) {
sine();
}
Gives you:
345678
12 901
90 2
8 34
67 5
5 6
4 7
3 8
2 9
1 0
0 1
2 2
3 1
4 0
56 9
7 8
8 67
9 5
01 34
23 12
4567890
Since this is Java, how about let's actually use some objects as objects rather than just as places to define a couple of functions.
Treat your wavy graph as if it is a composition of several different "branches" of the inverse sine function. (Mathematically, that's how we explain the way your version of the program uses Math.asin to produce multiple coordinates for stars.)
Branch 0 is the initial rising part of the curve,
Branch 1 is the falling part of the curve after Branch 0,
Branch 2 is the rising part of the curve after Branch 1, and so forth.
The branches cross the middle line of the output at x values 0,
PI, 2*PI, 3*PI, and so forth.
Depending on how far you want the graph to extend to the right, it is easy to determine how many branches you need.
For example, to plot from 0 to 8*PI you need nine branches
(Branch 0, Branch 8, and the seven branches between those two).
You can implement each branch using an object of some class,
let's call it ArcSineBranch.
It has a constructor, ArcSineBranch(int), that takes the branch number as a parameter.
Create some sort of ordered list (which could just be an ArcSineBranch[] array) and put these branch objects in it,
making sure the branch numbers go in sequence from 0 up to the largest number needed.
You'll also want to implement some way to tell the first ArcSineBranch where its leftmost end is--in the example in the question, the leftmost end of first branch is at y == 0, whereas for all other rising branches it is at y == -start and for all falling branches it is at y == start.
Now you call a mutator function of the first ArcSineBranch that tells it its leftmost symbol is 0. Treat this as an integer (rather than a string) for now to make the arithmetic easier.
You then query the first ArcSineBranch for the rightmost symbol it will write, which it can compute from the leftmost symbol and the number of lines it will write symbols on.
You also query it for the x coordinate of that rightmost symbol.
(The object computes the x-coordinate of the symbol for any y-coordinate by either adding or subtracting a rounded multiple of Math.asin(y / yPrecision) from a multiple of PI.)
Now for each ArcSineBranch in the list, you pass to it the rightmost symbol and x coordinate written by the previous branch.
This ArcSineBranch uses that information to determine the leftmost symbol it writes and the y coordinate of that symbol.
(I am being careful here about the y coordinate in case you choose a value of xPrecision that causes the rightmost x coordinate of one branch to be the same as the leftmost x coordinate of the next; we should only write one symbol at that place in the output, so we want the later branch to skip its leftmost x coordinate and write its leftmost symbol in the next place, one line up or down. But if the x coordinates are different we want the later branch to write a symbol on the same line.)
Now that the later ArcSineBranch "knows" the leftmost symbol it will print and thata symbol's y coordinate, you can query it for its rightmost symbol and x coordinate, and pass those to the next ArcSineBranch, and so forth.
Once you have traversed all the ArcSineBranch objects in this way,
so that each object knows what symbols need to be written for its branch and where to write them, you can loop for (y = start; y >= -start; y--);
within that loop you loop over the list of ArcSineBranch objects;
for each object you query whether it requires a symbol to be written at
y-coordinate y.
If the object requires a symbol to be written,
you query which symbol to write at which x-coordinate,
then space the output to the right until you reach that x-coordinate and write that symbol there.
But of course, first check that this would not plot a symbol beyond the
right-hand edge of the desired graph.
(This check really only applies to the last ArcSineBranch, so you can optimize the code a bit by looping over the other branches first and then dealing with the last ArcSineBranch separately.)
I've already described this algorithm in more detail than I initially wanted to. There should be enough information here to code this into Java in a relatively straightforward way, though there are still some localized details to be worked out.
Note that the design in this answer is intended to use the same mathematical ideas as the code in the question uses to decide where to plot the points.
Specifically, ArcSineBranch(0) produces the x1 values from the original code, ArcSineBranch(1) produces the x3 values, and ArcSineBranch(2) produces the x2 values.
The implementation of this design should plot a digit at the location of each star plotted by the original code, and should plot no other digits.
Care about a different approach?
3030
28 28
26 26
22 22
18 18
12 12
06 06
00 00 00
06 06
12 12
18 18
22 22
26 26
28 28
3030
Solution:
import static java.lang.Math.sin;
import static java.lang.Math.PI;
import static java.lang.Math.abs;
public class Sine {
static final Integer points = 30; // points on x and y axis
public static void main(String[] args) {
// contains graph points
Boolean[][] graph = new Boolean[points + 1][points + 1];
for (Double x = 0.0; x <= points; x++) {
// x axis pi value
Double pi = (x / points) * 2 * PI;
// sin(x) plot for x
Integer sinx = (int) Math.round((sin(pi) * points / 2) + points / 2);
graph[sinx][x.intValue()] = true;
}
for (Integer i = 0; i <= points; i++) {
for (Integer j = 0; j <= points; j++) {
// space characters on x axis
Integer pt = (int) Math.floor(Math.log10(points) + 1);
String space = String.format("%" + pt + "s", " ");
// padding for p
String p = String.format("%0" + (pt) + "d", abs(i - points / 2) * 2);
System.out.print(graph[i][j] != null ? p : space);
}
System.out.println();
}
}
}
Approach:
points contains the number of characters on x and y axis.
graph contains true or null for each x and y characters.
1st for loop:
Since the value of x in sine graph is from 0 to 2π, we need to convert x accordingly. So pi contains the value of the same range but according to x.
sinx is the Integer value according to x.
No need to explain graph[sinx][x.intValue()] = true;.
2nd for loops:
1st for loop
Execute LOOPLABEL.
Break to next line at the end.
2nd for loop(LOOPLABEL)
pt holds the number for padding on y axis.
space is the space characters to be printed on y axis.
p is the converted range between 0 to points.
Printing graph[i][j]
DEMO
By using the fact that each row has one point (on each slope), you can calculate which digit to display at each point without using extra memory or loops. Here's my example. Note that I only checked that this example only works if xPrecision and yPrecision are integers. You'll have to modify it if you want to use doubles.
class sine {
static final double xPrecision = 10.0; // (1/xPrecision) is the precision on x-values
static final double yPrecision = 10.0; // (1/yPrecision) is the precision on y-values
static final int PI = (int) Math.round(Math.PI * xPrecision);
static final int TPI = 2 * PI; // twice PI
static final int HPI = PI / 2; // half PI
static final int cycles = 2; // prints from x=0 to 2*cycles*pi
public static void main(String[] args) {
double xd;
int cycleoffset, cycleoffset2, topbottomoffset = 1;
for (int start = (int) (1 * yPrecision), y = start; y >= -start; y--) {
double x0 = Math.asin(y / yPrecision), x1 = bringXValueWithinPrecision(x0),
x2 = bringXValueWithinPrecision(x0 + TPI / xPrecision),
x3 = bringXValueWithinPrecision(PI / xPrecision - x0), tmp;
if (y == start) {
if (x1 == x3) // when there is only one point at the top/bottom
topbottomoffset = 0;
else if (x1 > x3) // swap x1 and x3
{
tmp = x1;
x1 = x3;
x3 = tmp;
}
} else if (y == -start) {
// I don't think this is needed, but just for safety make sure there is only one point on the bottom if there was only one point at the top
if (topbottomoffset == 0)
x2 = x3;
else if (x2 < x3) // swap x2 and x3
{
tmp = x2;
x2 = x3;
x3 = tmp;
}
}
cycleoffset = (int) (4 * yPrecision + 2 * topbottomoffset);
cycleoffset2 = -cycleoffset;
int start1 = topbottomoffset + 2 * (int) yPrecision, start2 = 2 * topbottomoffset + 4 * (int) yPrecision;
for (int x = 0, lim = cycles * TPI; x <= lim; x++) {
xd = ((x % TPI) / xPrecision);
if (x % TPI == 0)
cycleoffset2 += cycleoffset;
// x = 0 to pi/2
if (x1 == xd)
System.out.print((cycleoffset2 + y) % 10);
// x = 3pi/2 to 2pi
else if (x2 == xd)
System.out.print((cycleoffset2 + start2 + y) % 10);
// x = pi/2 to 3pi/2
else if (x3 == xd)
System.out.print((cycleoffset2 + start1 - y) % 10);
else
System.out.print(" ");
}
System.out.println();
}
}
public static double bringXValueWithinPrecision(double num) {
// obviously num has 16 floating points
// we need to get num within our precision
return Math.round(num * xPrecision) / xPrecision;
}
}
EDIT
The digits for the different ranges are calculated as follows
0 < x < π/2 : This one is simplest since it is the first range. Since the middle row is y=0 and that is where the sine wave starts, we can just use y to find the digit.
π/2 < x < 3π/2 : The digits here count up as we go down, but y decreases as we go down. So we have to use a -y term. On the top row, y=yPrecision, and the last digit from the previous range was yPrecision. So we use 2*yPrecision - y, because that includes the -y, and is equal to yPrecision at the first term (where y=yPrecision).
3π/2 < x < 2π : The digits here count down as we go down, so we need a +y term, but the tricky part is figuring where to start. Since the sine wave by this point has gone from 0 to yPrecision to 0 to -yPrecision, the bottom point (x=3π/2) should start at 3*yPrecision. Since y=-yPrecision at the bottom point, we use 4*yPrecision + y, since that includes a +y and is equal to 3*yPrecision at the first term (where y=-yPrecision).
The topbottomoffset term : Depending on the values used for xPrecision and yPrecision, there can be one or two points plotted on the top and bottom rows. If there are two points, we need to add one to digits in the π/2 to 3π/2 range, and two to the digits in the 3π/2 to 2π range.
The cycleoffset term : If multiple cycles of the sine wave are plotted, additional cycles need to start from the last digit used in the previous cycle. Each cycle goes from 0 to yPrecision to 0 to -yPrecision to 0, which is equal to 4*yPrecision. So each new cycle needs to start at 4*yPrecision*[the number of previous cycles]. If there are two points on the top and bottom rows, those need to be factored in as well.
Swapping values: When there are two points on the top row, then x1>x3. This happens because when y=yPrecision, we're taking Math.asin(1), which happens to be exactly pi/2=1.5707963267948966 in Java's double system. On lower xPrecision (<100.0), the rounding done by bringXValueWithinPrecision brings x1 up to 1.58 while x3 down to nearly 1.56. Hence, they need to be swapped in order to get the correct numerical order.
Here's my solution, which basically uses the half of the sine in 4 for loops:
from half to 0
from 0 to half
from half to the end
from the end to the half
And in each loop replace only the first asterisk.
class sine {
static final double xPrecision = 14.0; // (1/xPrecision) is the precision on x-values
static final double yPrecision = 14.0; // (1/yPrecision) is the precision on y-values
static final int PI = (int)(3.1415 * xPrecision);
static final int TPI = 2 * PI; // twice PI
static final int HPI = PI / 2; // half PI
public static void main(String[] args) {
double xd;
String str = "";
for (int start = (int)(1 * yPrecision), y = start; y >= -start; y--) {
double x0 = Math.asin(y / yPrecision),
x1 = bringXValueWithinPrecision(x0),
x2 = bringXValueWithinPrecision(x0 + TPI / xPrecision),
x3 = bringXValueWithinPrecision(PI / xPrecision - x0);
// for debug
//System.out.println(y + " " + x0 + " " + x1 + " " + x2 + " " + x3);
for (int x = 0; x <= TPI; x++) {
xd = (x / xPrecision);
if (x1 == xd || x2 == xd || x3 == xd)
str += "*";
else str += " ";
}
str += "\n";
}
String[] rows = str.split("\n");
int half = (int)(1 * yPrecision);
// we use this half in for loops, from half to 0, from 0 to half, from half to the end and from the end to the half, and replace only the first asterisk.
int val = 0;
for (int i = half; i >= 0; i--) {
if (val == 10) val = 0;
rows[i] = rows[i].replaceFirst("\\*", Integer.toString(val++));
}
for (int i = 0; i <= half; i++) {
if (val == 10) val = 0;
rows[i] = rows[i].replaceFirst("\\*", Integer.toString(val++));
}
for (int i = half + 1; i < rows.length; i++) {
if (val == 10) val = 0;
rows[i] = rows[i].replaceFirst("\\*", Integer.toString(val++));
}
for (int i = rows.length - 1; i >= half; i--) {
if (val == 10) val = 0;
rows[i] = rows[i].replaceFirst("\\*", Integer.toString(val++));
}
System.out.println(String.join("\n", rows));
}
public static double bringXValueWithinPrecision(double num) {
// obviously num has 16 floating points
// we need to get num within our precision
return Math.round(num * xPrecision) / xPrecision;
}
}
Result:
01
9 2
8 3
7 4
6 5
5 6
4 7
3 8
2 9
1 0
0 1 2
2 1
3 0
4 9
5 8
6 7
7 6
8 5
9 4
0 3
12
Add a counter in your loop and reset it when 9 is reached:
for(int x = 0, counter = 0; x <= TPI; x++, counter++){
xd = (x / xPrecision);
if(x1 == xd || x2 == xd || x3 == xd) {
System.out.print("" + counter);
if (counter == 9) {
counter = 0;
}
} else {
System.out.print(" ");
}
}
I have this class:
public class Vehicle {
private float speed;
public void decelerationSpeed()
{
--speed;
}
}
Each time decelerationSpeed method have been called speed variable decreased by one.
I need to change decelerationSpeed method this way that, if speed variable reached to zero and decelerationSpeed method have been called the speed value doesn't have to be changed.
In this tutorial I can't use if else or any other conditional operators(I think I have to manipulate with modulo and divide operations).
We always want to subtract by one except when our speed is zero so the modulo operation is appropriate as 0 mod y is 0 while for any other number we want x mod y to result in 1. The modulo operation that fits these criteria is x % (x - 1) The two corner cases then are 1 and 2 where 1 would give modulus of 0 and 2 mod 1 would have no effect. So we exclude them from the possible set of values with preliminary addition and subsequent subtraction:
public void decelerationSpeed()
{
speed = speed + 2;
speed = speed - ((speed) % (speed-1));
speed = speed - 2;
}
I don't know if bit conversions are allowed but here is a solution:
speed -= 1;
int bits = Float.floatToRawIntBits(speed);
bits &= (bits >>> 31) - 1;
speed = Float.intBitsToFloat(bits);
So, first we get the sign bit (bits >>> 31) and subtract one from it to get a mask: 0xffffffff for positive numbers and 0x00000000 for negative numbers. Using this will change every negative number to +0.
It's not a pretty solution but it works.
A nice solution using javas floatingpoint to integer-conversion would look like this:
speed -= (int) ((speed / (speed + 1.0) + 0.6));
The basic idea is that java converts floatingpoint numbers to integers by discarding the decimal places. Thus we only need a way to generate a value v, in a way such that 0 <= v < 1, if the input is 0 and 1 <= v < 2 else. speed / (speed + 1.0) provides the property of being 0, if speed is 0, otherwise it's at least 0.5 and at most (mathematically at least) nearly 1. Just shift all of this by 0.6 (to make sure we definitely get above 1) and we've got the require sequence. The rest is just cutting away the decimal places and we're there.
A really ugly (but simpler) way would be the following:
void decrement()
{
try{
int throwaway = 1 / speed;
speed--;
}catch(ArithmeticException e){
//just ignore the exception
}
}
If you can use the Math.sqrt function then its possible using the following equation.
(val+|val|)/2
Basically any negative numbers will subtract from itself becoming 0.
Heres some code showing it
public static float decelerationSpeed(float speed) {
speed -= 1; // subtract
// use (val+|val|)/2 to zero out any negative numbers. Divide by 2 to return to origional number
return (float) (speed+Math.sqrt(speed*speed))/2f;
}
public static void main(String [] args) throws Exception {
System.out.println(assertF(decelerationSpeed(-10), 0));
System.out.println(assertF(decelerationSpeed(10), 9));
System.out.println(assertF(decelerationSpeed(-2), 0));
System.out.println(assertF(decelerationSpeed(2), 1));
System.out.println(assertF(decelerationSpeed(-1), 0));
System.out.println(assertF(decelerationSpeed(1), 0));
System.out.println(assertF(decelerationSpeed(-0), 0));
System.out.println(assertF(decelerationSpeed(0), 0));
}
public static float assertF(float actual, float expected) {
if(actual != expected) throw new IllegalStateException("Expected "+expected+" but got "+actual);
return actual;
}
This is how I would answer this question. Works passing in int, short, float, or double, etc.:
public class HelloWorld
{
private static float speed = 1113; // initial speed
private static short smallIncrement = 13;
public static void main(String[] args)
{
decelerateAndReturnSpeed(2.33); // prints 1110.67
decelerateAndReturnSpeed(7.33f); // prints 1103.3401
decelerateAndReturnSpeed(113); // prints 990.3401
decelerateAndReturnSpeed(smallIncrement); // prints 977.3401
}
public static float decelerateAndReturnSpeed(double vAmt)
{
speed -= vAmt;
if (speed < 0) speed = 0;
System.out.println(speed);
return speed;
}
}
Now, this is because the compiler computes like this, with a implicit cast:
speed = (float)(speed -vAmt); // same as speed =- vAmt
I'm running into an issue in which the minima is not being correctly set. The maxima is setting perfectly, but I know that the minima should be less than 0. Running this snippet, it seems like the minima is never being set. Any ideas?
edit: The curve points should be from -1 to 3. Here's an image:
public class FindingExtrema {
public static void main(String[] args) {
double lowestPoint = 0;
double highestPoint = 0;
double y;
double x = -1;
int timesCalculated = 0;
while (x <= 3) {
y = run(x);
if (y < lowestPoint) {
lowestPoint = y;
System.out.printf("y: %1$.5f", y);
}
if (y > highestPoint) {
highestPoint = y;
}
x += .00001;
timesCalculated++;
}
System.out.println("Done!");
System.out.printf("Lowest: %1$.5f, Highest: %2$.5f; Calculated %3$d times\n", lowestPoint, highestPoint, timesCalculated);
}
private static double run(double x) {
return Math.cbrt(2 * x) - Math.sqrt(8 * x) + x + 16;
}
}
but I know that the minima should be less than 0.
It isn't, if you graph it. I plugged your function into Google for the range 0 to 3 and the minimum was something like 15.431.
The expression
Math.cbrt(2 * x) - Math.sqrt(8 * x) + x + 16;
is not equivalent to the right hand side for the equation of your graph - you are getting cube root confused with cubing and square root confused with squaring.
The correct expression is
(2 * x * x * x) - (8 * x * x) + x + 16
Make your lowestPoint point as follows.
double lowestPoint = 1000;
Could you please put the original equation? you can't find square root for minus value.
sqrt
public static double sqrt(double a)
Returns the correctly rounded positive square root of a double value. Special cases: ◦If the argument is NaN or less than zero, then the result is NaN.
◦If the argument is positive infinity, then the result is positive infinity.
◦If the argument is positive zero or negative zero, then the result is the same as the argument.
Otherwise, the result is the double value closest to the true mathematical square root of the argument value.Parameters:a - a value.Returns:the positive square root of a. If the argument is NaN or less than zero, the result is NaN.
I want to round the number 1732 to the nearest ten, hundred and thousand. I tried with Math round functions, but it was written only for float and double. How to do this for Integer? Is there any function in java?
What rounding mechanism do you want to use? Here's a primitive approach, for positive numbers:
int roundedNumber = (number + 500) / 1000 * 1000;
This will bring something like 1499 to 1000 and 1500 to 2000.
If you could have negative numbers:
int offset = (number >= 0) ? 500 : -500;
int roundedNumber = (number + offset) / 1000 * 1000;
(int)(Math.round( 1732 / 10.0) * 10)
Math.round(double) takes the double and then rounds up as an nearest integer. So, 1732 will become 173.2 (input parameter) on processing by Math.round(1732 / 10.0). So the method rounds it like 173.0. Then multiplying it with 10 (Math.round( 1732 / 10.0) * 10) gives the rounded down answer, which is 173.0 will then be casted to int.
Use Precision (Apache Commons Math 3.1.1)
Precision.round(double, scale); // return double
Precision.round(float, scale); // return float
Use MathUtils (Apache Commons Math) - Older versions
MathUtils.round(double, scale); // return double
MathUtils.round(float, scale); // return float
scale - The number of digits to the right of the decimal point. (+/-)
Discarded because method round(float,
scale) be used.
Math.round(MathUtils.round(1732, -1)); // nearest ten, 1730
Math.round(MathUtils.round(1732, -2)); // nearest hundred, 1700
Math.round(MathUtils.round(1732, -3)); // nearest thousand, 2000
Better solution
int i = 1732;
MathUtils.round((double) i, -1); // nearest ten, 1730.0
MathUtils.round((double) i, -2); // nearest hundred, 1700.0
MathUtils.round((double) i, -3); // nearest thousand, 2000.0
You could try:
int y = 1732;
int x = y - y % 10;
The result will be 1730.
Edit: This doesn't answer the question. It simply removes part of the number but doesn't "round to the nearest".
At nearest ten:
int i = 1986;
int result;
result = i%10 > 5 ? ((i/10)*10)+10 : (i/10)*10;
(Add zero's at will for hundred and thousand).
why not just check the unit digit...
1. if it is less than or equal to 5, add 0 at the unit position and leave the number as it is.
2. if it is more than 5, increment the tens digit, add 0 at the unit position.
ex: 1736 (since 6 >=5) the rounded number will be 1740.
now for 1432 (since 2 <5 ) the rounded number will be 1430....
I hope this will work... if not than let me know about those cases...
Happy Programming,
very simple. try this
int y = 173256457;int x = (y/10)*10;
Now in this you can replace 10 by 100,1000 and so on....
Its very easy..
int x = 1234;
int y = x - x % 10; //It will give 1230
int y = x - x % 100; //It will give 1200
int y = x - x % 1000; //It will give 1000
The above logic will just convert the last digits to 0. If you want actual round of//
For eg. 1278 this should round off to 1280 because last digit 8 > 5 for this i wrote a function check it out.
private double returnAfterRoundDigitNum(double paramNumber, int noOfDigit)
{
double tempSubtractNum = paramNumber%(10*noOfDigit);
double tempResultNum = (paramNumber - tempSubtractNum);
if(tempSubtractNum >= (5*noOfDigit))
{
tempResultNum = tempResultNum + (10*noOfDigit);
}
return tempResultNum;
}
Here pass 2 parameters one is the number and the other is position till which you have to round off.
Regards,
Abhinav
I usually do it this way:
int num = 1732;
int roundedNum = Math.round((num + 9)/10 * 10);
This will give you 1740 as the result.
Hope this will help.
int val2 = 1732;
val2 = (int)(Math.rint((double) i / 10) * 10);
The output is:1730
Have you looked at the implementation of Mathutils.round() ? It's all based on BigDecimal and string conversions. Hard to imagine many approaches that are less efficient.
Without using any math utils, rounding could be achieved to any unit as below:
double roundValue (double input, double toNearest){
//toNearest is any rounding base like 10, 100 or 1000.
double modValue = input % toNearest;
System.out.println(modValue);
if(modValue == 0d){
roundedValue = input;
}
else
{
roundedValue = ((input - modValue) + toNearest);
}
System.out.println(roundedValue);
return roundedValue;
}