im trying to program a little java program, that finds null points in a given function f(x).
This is my idea:
I have X1 and X2 (User input) to define an area where to search for the null point. For example -5 and 5.
private static double Naehern(double X, double X2) {
double Y = -1;
double Step = 0.01;
while(Y < -0.00001 || Y > 0.00001) {
X = X + Step;
Y = f(X);
if(X >= X2) {
break;
}
}
return X;
}
static double f(double x) {
return x * x;
}
I am trying to find a Point X, between X1 and X2, where our null point is with an accuracy of about 5. So, in my while() i am starting at X1 and keep checking for X1 while adding +0,01 to it. At some point it should find a null point.
Problems in my current idea:
When starting with -5 for X1 and 5 for X2, the following happens:
X: -4,99
X: -4,98
X: -4,9700000000000000001
How can i fix this by still using doubles?
Secondly i am getting this number at the end of the program: -6.230779781013496E-14. This is the found null point at X = -6.230779781013496E-14. How can I convert this number into something like a normal-readable double with 5 characters after the "."?
a) you can't, unless you use a step width that is exactly representable in binary, like 1/128 instead of 1/100 (which is not).
b) You can use printf("%.5f", ...), though in your case, the output would be just 0.00000.
You can use System.out.printf, String.format or NumberFormat class to format numbers.
Floats and doubles are not exact values. If you want higher precision, there are better ways than float/double. Yes, BigDecimal, I am looking at you.
Related
I want to convert a double value to int when and only when 2 numbers after the dot are 0.
Example
double x = 25.001
You can use this :
double x = 25.001;
int i = (int) x;
System.out.println(x);//Input
if (x - i <= 0.01) {
x = (int) x;
}
System.out.println(x);//Output
RESULT
Input Output
25.001 25.0
25.011 25.011
If you want to use a second variable you can use :
int y = 0;
if (x - i <= 0.01) {
y = (int) x;
}
Note
But note, in case your input is not correct, you will always get 0, i like the first solution it is good then the second.
if(x-Integer.parseInt(x)>=0.001)
//Convert here
That rounded number you then cannot store in a double, as a double is always an approximation of a real value - of a series of a (negative) power of 2.
So you should go for BigDecimal as many do that want to do financial software.
If you did something like:
double adjustWhenCloseToInt(double x) {
long n = Math.round(x); // Could overflow for large doubles
if (Math.abs(x - n) < 0.01) {
x = n;
}
return x;
}
A simple
x = adjustWhenCloseToInt(x);
System.out.print(x);
Could still print 0.00000001 or such.
The solution there is
System.out.printf("%.2f", x);
Or better use a localized MessageFormat (thousand separators and such).
As floating point always bears rounding errors, I would in general go for BigDecimal, though it is a circumstantial class to use. Take care to use String constructors:
new BigDecimal("3.99");
As they then can maintain a precision of 2.
This question already has answers here:
Division of integers in Java [duplicate]
(7 answers)
Closed 6 years ago.
When dividing two 'int' variables and saving the result into a 'double' variable, anything to the right of the decimal point is just zero?
See the three examples below.
Thank you in advance, Mike
Example 1
public class MyClass {
public static void main(String[] args) {
int x, y, answer;
x = 70;
y = 30;
answer = x / y;
System.out.print(answer);
}
}
Output = 2 (I understand the result, all variables defined as 'int')
Example 2
public class MyClass {
public static void main(String[] args) {
int x, y;
double answer;
x = 70;
y = 30;
answer = x / y;
System.out.print(answer);
}
}
Output = 2.0 (I don't understand the result, the variable answer is 'double' and I expected 2.3333333333333335)
Example 3
public class MyClass {
public static void main(String[] args) {
double x, y, answer;
x = 70;
y = 30;
answer = x / y;
System.out.print(answer);
}
}
Output = 2.3333333333333335 (I understand the result, all variables defined as 'double')
Let's get a closer look at how Java executes this line in the second piece of code:
answer = x / y;
First, Java sees a = operator so it knows that this is an assignment statement. To evaluate an assignment, evaluate the expression on the rignt then put the result into the variable on the left. Therefore, it evaluates the right hand side first.
x / y
Hmm... what could be the result of that? x is an int and y is an int and you have a / operator. I know the division operator can be applied to two int operands, so let me get the value of x and y. Ah! It's 70 / 30! Since it is an integer divided by an integer, the result must be an integer! The result is 2!
Now the assignment becomes:
answer = 2;
Java finds an integer on the right and a double variable on the left, so it converts 2 into a double and puts it in the variable.
Dividing two integers will yield an integer (which is 2 in this case). It just so happens that you chose to store this integer in a double, so it is now represented as 2.0.
The first code reads everything as int and gives an int. The second code reads two ints and gives the double of the ints (example: 10/5 = 2, but 2 in double is 2.0). In the end the third code reads everything as double so for example 70/30 (read as 70.0/30.0) = 2.33...
The Example 2, when compute answer = x / y, the first compute x / y and result is 2 then convert the double type 2.0.
I have two equations: x * x - D * y * y = 1 and x = sqrt(1 + D * y * y).
Both are algebraic manipulations of the other.
Given D, I need to solve for the smallest integer value of x so that y is also an integer. I loop through possible y values, plug them into the second equation and test if x is an integer. If it is, I return x.
The problem I have is when x, y, and D are plugged into the 1st equation, it does not equal 1.
These are some problematic values:
1. x=335159612 y=42912791 D=61
2. x=372326272 y=35662389 D=109
My intuition is that java's Math.sqrt method does not calculate such a small decimal, however BigDecimal does not have a square root method.
Is my math just wrong? If not, what can I do to accurately calculate x and y?
Edit: Here is the root of the problem along with the method that tests if a double is a a natural number.
public static void main(String[] args){
long x = 335159612, D = 61, y = 42912791;
System.out.println(Math.sqrt(D * y * y + 2)); // 3.35159612E8
System.out.println(x * x - D * y * y); // 3
}
public static boolean isNatural(double d){
return d == (int)d;
}
Be careful with precisions in 'double'.
As per IEEE 754-1985 the double precision provides 16 digits (15,9 to be absolutely precise).
E.g.
a) SQRT(112331965515990542) is
335159611.99999999701634694576505237017910
Which, when converted into double, gives 3.3515961199999999E8
b) SQRT(112331965515990543)
335159611.99999999850817347288252618840968
Which, when converted into double, gives 3.3515961199999999E8.
So, as per IEEE 754-1985 definition, those values are equal.
Apparently, any further logical/mathematical checks will be, generally speaking, inaccurate.
To overcome this limitation I recommend BigMath package from www.javasoft.ch
import ch.javasoft.math.BigMath;
import java.math.BigDecimal;
class Tester {
public static void main(String[] args) {
long D = 61L, y = 42912791L;
double a = Math.sqrt(D * y * y + 1);
double b = Math.sqrt(D * y * y + 2);
System.out.println(a);
System.out.println(b);
System.out.println(a == b);
BigDecimal bda = BigMath.sqrt(new BigDecimal(D * y * y + 1), 32);
BigDecimal bdb = BigMath.sqrt(new BigDecimal(D * y * y + 2), 32);
System.out.println(bda.toString());
System.out.println(bdb.toString());
System.out.println(bda.equals(bdb));
}
}
Result:
3.35159612E8
3.35159612E8
true
335159611.99999999701634694576505237017910
335159611.99999999850817347288252618840968
false
P.s. to completely ruin your faith in standard Java maths try this:
System.out.println(0.9200000000000002);
System.out.println(0.9200000000000001);
You will see:
0.9200000000000002
0.9200000000000002
This kind of Diophantine's equations is known as Pell's equations.
Wiki.
Mathworld.
Both links contain clues - how to solve this equation using continued fractions.
I think it would be nice to apply some math instead of brutforce/
If sqrt is the issue, use the first equation instead. If x is an integer, x^2 will also be an integer; if x is not an integer, then x^2 would also not be an integer, as long as you are using BigDecimals with sufficient scale for your math and not doubles.
Hi I'm trying to run a calculation but I can't seem to put it all on one line, I have to split the result into two seperate lines to achieve the desired result (which seems a bit long winded).
Can anyone explain where I'm going wrong?
both x and y are doubles.
Example 1: (incorrect)
y=0.68
x= (Math.round(y* 10))/10;
result x=0
Example 2: (correct)
y=0.68
x= Math.round(y* 10);
x = x/10;
result x=0.7
thanks for your time.
Math.round returns variable of type long (see: Javadoc), which means that the division by 10 is performed on a long variable resulting in another long variable - that's why you lose the precision.
To make it calculate on it as on double and return double - you have to cast the result of Math.round like this:
x= ((double)Math.round(y* 10))/10;
Have you tried to explicitly specify double in your calculation:
x = ((double)Math.round( y * 10.0)) / 10.0;
Math.round returns a long....
It's hard to tell from your snippets, because they don't include variable types, but it's likely to be integer division that's killing you. When you divide two integers x and y, where x < y, you get zero:
int x = 4;
int y = 10;
int z = x/y; // this is zero.
y=0.68
x= (Math.round(y* 10)) <--- Evaluated as int since Math.round returns int /10; <-- integer division
result x=0
y=0.68
x= Math.round(y* 10) <-- x is stored as double
x = x/10; <-- double division
result x=7
I guess it's because Math.round returns either a long or an int, depending on whether y is double or float. an then you have an integer division.
in the second example x is already a double and that's why you have a double division.
When you write:
double x = (Math.round(y* 10))/10;
(Math.round(y* 10)) is a long (= 7), which you divide by 10, that gives another long (= 0). The result is then converted back to a double and stored in x.
In your second snippet:
double x = Math.round(y* 10);
This is equal to 7 and converted into a double. x / 10 is then a double operation that returns 0.7.
I need to cast a double to an int in Java, but the numerical value must always round down. i.e. 99.99999999 -> 99
Casting to an int implicitly drops any decimal. No need to call Math.floor() (assuming positive numbers)
Simply typecast with (int), e.g.:
System.out.println((int)(99.9999)); // Prints 99
This being said, it does have a different behavior from Math.floor which rounds towards negative infinity (#Chris Wong)
To cast a double to an int and have it be rounded to the nearest integer (i.e. unlike the typical (int)(1.8) and (int)(1.2), which will both "round down" towards 0 and return 1), simply add 0.5 to the double that you will typecast to an int.
For example, if we have
double a = 1.2;
double b = 1.8;
Then the following typecasting expressions for x and y and will return the rounded-down values (x = 1 and y = 1):
int x = (int)(a); // This equals (int)(1.2) --> 1
int y = (int)(b); // This equals (int)(1.8) --> 1
But by adding 0.5 to each, we will obtain the rounded-to-closest-integer result that we may desire in some cases (x = 1 and y = 2):
int x = (int)(a + 0.5); // This equals (int)(1.8) --> 1
int y = (int)(b + 0.5); // This equals (int)(2.3) --> 2
As a small note, this method also allows you to control the threshold at which the double is rounded up or down upon (int) typecasting.
(int)(a + 0.8);
to typecast. This will only round up to (int)a + 1 whenever the decimal values are greater than or equal to 0.2. That is, by adding 0.8 to the double immediately before typecasting, 10.15 and 10.03 will be rounded down to 10 upon (int) typecasting, but 10.23 and 10.7 will be rounded up to 11.
(int)99.99999
It will be 99.
Casting a double to an int does not round, it'll discard the fraction part.
Math.floor(n)
where n is a double. This'll actually return a double, it seems, so make sure that you typecast it after.
This works fine int i = (int) dbl;
new Double(99.9999).intValue()
try with this, This is simple
double x= 20.22889909008;
int a = (int) x;
this will return a=20
or try with this:-
Double x = 20.22889909008;
Integer a = x.intValue();
this will return a=20
or try with this:-
double x= 20.22889909008;
System.out.println("===="+(int)x);
this will return ===20
may be these code will help you.
Try using Math.floor.
In this question:
1.Casting double to integer is very easy task.
2.But it's not rounding double value to the nearest decimal. Therefore casting can be done like this:
double d=99.99999999;
int i=(int)d;
System.out.println(i);
and it will print 99, but rounding hasn't been done.
Thus for rounding we can use,
double d=99.99999999;
System.out.println( Math.round(d));
This will print the output of 100.