This is how I am creating q
Double q = ((r * (i/5)) + y);
at this point the values of the other variables are
r = 3.470694142992069E-5
i = 1
y = -116.30237535361584
but
q = -116.30237535361584
is there something wrong with this math? ( Java )
q should be -116.30236841222755
i and 5 are both integers, so the (i/5) portion evaluates to an integer (0). That negates the multiplication by r, so you're left with only the value for y.
Try
Double q = ((r * ((double)i/5)) + y);
Here's the complete code.
class Main
{
public static void main (String[] args) throws java.lang.Exception
{
double r = 3.470694142992069E-5;
int i = 1;
double y = -116.30237535361584;
Double q = ((r * ((double)i/5)) + y);
System.out.println(q);
}
}
Output:
-116.30236841222755
If i is an integer (which seems to be the case), then the i/5 expression will perform integer math resulting in zero.
i is not a double. Integer division floors. Anything times 0 is 0.
maybe you can try
Double q = ((r * i/5.0) + y);
Floating point values are notoriously imprecise. The difference you're showing can be expected for double arithmetic. If you really need the extra precision, jquantity is an open source Java library for precise math.
Related
My task is to implement the cos(x) function withou using Math. library and with the taylor polynom, my code looks like this:
public class Cosinus {
public static void main(String[] args) {
/*if(args.length == 0){
System.out.println("ERROR: Geben Sie ein Argument für x ein!");
return;
}*/
double x = 5;
double summand1 = (x*x) / 2;
double summand2 = (x*x*x*x) / (2*3*4);
double summand3 = (x*x*x*x*x*x) / (2*3*4*5*6);
double summand4 = (x*x*x*x*x*x*x*x) / (2*3*4*5*6*7*8);
double summand5 = (x*x*x*x*x*x*x*x*x*x) / (2*3*4*5*6*7*8*9*10);
double summand6 = (x*x*x*x*x*x*x*x*x*x*x*x) / (2*3*4*5*6*7*8*9*10*11*12);
double summand7 = (x*x*x*x*x*x*x*x*x*x*x*x*x*x) / (2*3*4*5*6*7*8*9*10*11*12*13*14);
//double summand8 = (x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x) / (2*3*4*5*6*7*8*9*10*11*12*13*14*15*16);
//double summand9 = (x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x) / (2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18);
//double summand10 = (x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x) / (2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18*19*20);
double cosinusFunktion = (((((((1 - summand1) + summand2) - summand3) + summand4) - summand5) + summand6) - summand7);
System.out.println(cosinusFunktion);
}
}
For x = 1, 2, 3, and 4 Y is between 1 and -1
but with x = 5 it goes too -4 and if the x are even getting bigger this continues too 1287918274.
I cant solve this task but tthe task says it is enough to implement this funktion iwth the taylor polynom and the first 11 summand. I tried this too, but then even with x = 1 the bounds are broken. How can i solve this, so x = 42.5 is in bound of -1 and 1?
Tried more summands to make the result more excact, but the bounds get broken even more.
tried implement the periodicity of x-2*PI, but I dont know where to put it and results get messed up eeven more.
you are getting an integer overflow for the factorial in the summand7 line
as a simple fix you can change the line to:
double summand7 = (x*x*x*x*x*x*x*x*x*x*x*x*x*x) / ((double) 2*3*4*5*6*7*8*9*10*11*12*13*14);
The Taylor expansion will always blow up for larger inputs. However, since:
sin(x) = sin(x + n*2*pi) // for any integer n
You can simply pre-process you input with a modulus function to prevent your output from blowing up.
I can't test compile right now, but if memory serves, you would add one of the following lines prior to computing your first summand:
x = x%(Math.PI*2)
Or, if you can't use Math
x = x%((double)3.14159265358979323846*2)
I was trying to figure out a way to calculate modulo inverse using java so I wrote this function to do it:
public static int privatekey(int primeprod, int e, int lambda)
{
Random random = new Random();
float d = 0;
//extended euler's theorem is
//d = (1 + x*lambda) / e
//d is smaller than primeprod
while(true)
{
int d = random.nextInt(200) + 1;
System.out.println("seed: "+x);
var = (1 + (x*lambda)) / e;
System.out.println("var: "+d);
if(isInteger(d) && d < primeprod)
{
break;
}
}
int finalvar = (int)d;
return finalvar;
}
I felt that it was going wrong so I reversed euclidean theorem extension I used above as follows
1 + x.lambda
------------- = d (this one is the equation to find out d when x is any integer)
e
de = 1 + x.lambda
de - 1 = x.lambda
de - 1
------- = x (this one is to check whether the value obtained by the above equation is true or not by checking if x is the same value we had chosen for our calculation in the first place)
lambda
After doing this check I found that the value of x I obtained in the reversed equation I had solved to check for mistakes is not equal but approximate to the original random value which I had generated.
For example taking these values:
e = 327
lambda = 484
x = 76
We get d as 112.0
later We reverse The equation to find the value of x to confirm
we get:
x = 75.667355372 (Which is approximate to the original value)
I wasn't able to figure out where it was going wrong.
To look at the full program please visit this link.
Please tell me If I have done something wrong here.
Thank You in advance!
Alright I got an answer to this problem.
The Issue was I was performing arithmetic operations on integer so the value I got as result was an integer.
Instead of using integer I later used Double to do the same operation and I resolved the issue.
public static int privatekey(Double primeprod, Double e, Double lambda)
{
Random random = new Random();
float d = 0;
//extended euler's theorem is
//d = (1 + x*lambda) / e
//d is smaller than primeprod
while(true)
{
int d = random.nextInt(200) + 1;
System.out.println("seed: "+x);
var = (1 + (x*lambda)) / e;
System.out.println("var: "+d);
if(isInteger(d) && d < primeprod)
{
break;
}
}
int finalvar = (int)d;
return finalvar;
}
This resolved the issue.
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.