Finding square roots without sqrt() to .000001 precision - java

I'm working on making a method that will calculate the square root of a supplied integer without using Math.sqrt(). I believe everything is working except for meeting the condition of the while loop.
As of right now perfect squares will work however non perfect squares seem to loop infinitely. I'm not sure how to get it meet the conditions of the loop to break and find the square root of a non perfect square to a precision of .000001.
public static double findSquareRoot(int value)
{
value = Math.abs(value);
double mid = value / 2.0, answer = 0;
// loop until sqrt is found
while (answer * answer != value)
{
// if middle value is sqrt
if (mid * mid == value)
{
return mid;
}
// if middle value is too big to be sqrt
else if (mid * mid > value)
{
mid = mid / 2.0;
answer = mid;
}
// if middle value is too small to be sqrt
else
{
mid = (mid + value) / 2.0;
answer = mid;
}
}
return answer;
}

You need to check with given precision:
public static double findSquareRoot(int value)
{
private static final double PRECISION = 0.000001;
value = Math.abs(value);
double mid = value / 2.0, answer = 0;
// loop until sqrt is found
while (Math.abs(answer * answer - value) < PRECISION)
{
// if middle value is sqrt
if (Math.abs(mid * mid - value) < PRECISION)
{
return mid;
}
// if middle value is too big to be sqrt
else if (mid * mid > value)
{
mid = mid / 2.0;
answer = mid;
}
// if middle value is too small to be sqrt
else
{
mid = (mid + value) / 2.0;
answer = mid;
}
}
return answer;
}

This should work for non perfect square. Basically, as #Andronicus indicated, you need to check against the precision in the while condition clause.
private static double getSqrt(int x) {
final double PRECISION = 0.000001;
x = Math.abs(x);
double start = 1, end = (double )x, ans=0.0, mid = 0.0;
while (Math.abs(mid*mid - x) > PRECISION) {
//use binary search
mid = (start + end) / 2.0;
// continue to narrow the range
if (mid * mid < x) {
start = mid + 0.5;
ans = mid;
}
else {
end = mid - 0.5;
}
}
return ans;
}

Related

I want to make a function to find the closest value to n such that 32 % n = 0 in Java

I'm trying to make an efficient function that's described in the title of this question. Here is what I have tried, but I'm sure their is a better way. I'm using Java 8
Question: Is their a better way to implement this function that is more efficient?
private static double nearestMod(double n) {
// Check if n already satisfies the condition
if (32 % n == 0) {
return n;
}
// Check if the solution can't be reasonably obtained
if (n > 32) {
return -1;
}
double increment;
int numsAfterDecimalPoint = String.valueOf(n).split("\\.")[1].length();
if (n % 1 == 0) {
// If n is a whole number
increment = 10;
} else {
increment = 1d / Math.pow(10, numsAfterDecimalPoint - 1);
}
double result = Double.MAX_VALUE;
double multiplier = increment == 10 ? 1 : Math.pow(10, numsAfterDecimalPoint);
for (double i = n - increment * multiplier; i < n + increment * multiplier; i += increment / 10d) {
double check = 32 / i;
if (Math.abs(Math.round(check) - check) < increment / 10d && Math.abs(i - n) < Math.abs(result - n)) {
result = i;
}
}
return result;
}
Example:
nearestMod(0.26) should return 0.25

Find nearest double in ordered ArrayList<Double>

I have an sorted ArrayList and I would like to find nearest element to double x in it.
double x = 50.2;
ArrayList<Double> arrayList = new ArrayList<>();
arrayList.add(12.34);
arrayList.add(86.00);
arrayList.add(87.26);
arrayList.add(241.63);
...
double findNearestDoubleInList(list, x)
{
...
}
How do I accomplish that?
Use java.lang.Math.abs to get the difference between values in the list and desired value and find the nearest one.
double answer = arrayList.get(0);
double current = Double.MAX_VALUE;
for (Double value : arrayList) {
if (Math.abs(value - x) < current) {
answer = value;
current = Math.abs(value - x);
}
}
Walk through the list and compute the absolute difference with x and the current element in the list.
Return the smallest absolute difference.
static double findNearestDoubleInList(ArrayList<Double> list, double d){
if(list.size() == 0){
return -1;
}
if(list.size() == 1){
return list.get(0);
}
double current = list.get(0);
double currentMin = Math.abs(list.get(0) - d);
for(int i = 1; i < list.size(); i ++){
double difference = Math.abs(list.get(i) - d);
if(currentMin > difference){
currentMin = difference;
current = list.get(i);
}
}
return current;
}
For algorithms like this, always assume the first element is your solution.
// Java program to find element closet to given target by binary search on the sorted array
class FindClosestNumber {
// Returns element closest to target in arr[]
public static double findClosest(double[] arr, double target)
{
int n = arr.length;
// Corner cases
if (target <= arr[0])
return arr[0];
if (target >= arr[n - 1])
return arr[n - 1];
// Doing binary search
int i = 0, j = n, mid = 0;
while (i < j) {
mid = (i + j) / 2;
// if arr[mid] and target are very close
if (Math.abs(arr[mid]-target) < 0.0001)
return arr[mid];
/* If target is less than array element,
then search in left */
if (target < arr[mid]) {
// If target is greater than previous
// to mid, return closest of two
if (mid > 0 && target > arr[mid - 1])
return getClosest(arr[mid - 1],
arr[mid], target);
/* Repeat for left half */
j = mid;
}
// If target is greater than mid
else {
if (mid < n-1 && target < arr[mid + 1])
return getClosest(arr[mid],
arr[mid + 1], target);
i = mid + 1; // update i
}
}
// Only single element left after search
return arr[mid];
}
// Method to compare which one is the more close
// We find the closest by taking the difference
// between the target and both values. It assumes
// that val2 is greater than val1 and target lies
// between these two.
public static double getClosest(double val1, double val2,
double target)
{
if (target - val1 >= val2 - target)
return val2;
else
return val1;
}
// Driver code
public static void main(String[] args)
{
double arr[] = {12.34, 86.00, 87.26, 241.63};
double target = 50.2;
System.out.println(findClosest(arr, target));
}
}

calculate double negative exponent

I want to know how to calculate this equation in Java considering that the exponent can be negative
equation example:
D_DL=10^((149.874-69.55-26.16 log_10(900)+13.82 log_10(60)+1.115)/([44.9-6.55 log_10(60)]))
Here I'm trying to calculate my exponent
double exposantD = ( Mapldl_s - 69.55 -( 26.16 * Math.log10(_BF_) )+ (13.82 * Math.log10(HB_)) + _ahm_) / (44.9 - (6.55 *Math.log10(HB_)));
I try with this function :
public static double powMyExpo(double base, double exponent) {
double result = 1;
if (exponent == 0) {
return result;
}
if (exponent < 0) {
return 1 / powMyExpo(base, exponent * -1);
}
for (int i = 1; i <= exponent; i++) {
result = result * base;
}
return result;
}
but always result = 1
Thanks

how to get exponents without using the math.pow for java

This is my program
// ************************************************************
// PowersOf2.java
//
// Print out as many powers of 2 as the user requests
//
// ************************************************************
import java.util.Scanner;
public class PowersOf2 {
public static void main(String[] args)
{
int numPowersOf2; //How many powers of 2 to compute
int nextPowerOf2 = 1; //Current power of 2
int exponent= 1;
double x;
//Exponent for current power of 2 -- this
//also serves as a counter for the loop Scanner
Scanner scan = new Scanner(System.in);
System.out.println("How many powers of 2 would you like printed?");
numPowersOf2 = scan.nextInt();
System.out.println ("There will be " + numPowersOf2 + " powers of 2 printed");
//initialize exponent -- the first thing printed is 2 to the what?
while( exponent <= numPowersOf2)
{
double x1 = Math.pow(2, exponent);
System.out.println("2^" + exponent + " = " + x1);
exponent++;
}
//print out current power of 2
//find next power of 2 -- how do you get this from the last one?
//increment exponent
}
}
The thing is that I am not allowed to use the math.pow method, I need to find another way to get the correct answer in the while loop.
Powers of 2 can simply be computed by Bit Shift Operators
int exponent = ...
int powerOf2 = 1 << exponent;
Even for the more general form, you should not compute an exponent by "multiplying n times". Instead, you could do Exponentiation by squaring
Here is a post that allows both negative/positive power calculations.
https://stackoverflow.com/a/23003962/3538289
Function to handle +/- exponents with O(log(n)) complexity.
double power(double x, int n){
if(n==0)
return 1;
if(n<0){
x = 1.0/x;
n = -n;
}
double ret = power(x,n/2);
ret = ret * ret;
if(n%2!=0)
ret = ret * x;
return ret;
}
You could implement your own power function.
The complexity of the power function depends on your requirements and constraints.
For example, you may constraint exponents to be only positive integer.
Here's an example of power function:
public static double power(double base, int exponent) {
double ans = 1;
if (exponent != 0) {
int absExponent = exponent > 0 ? exponent : (-1) * exponent;
for (int i = 1; i <= absExponent; i++) {
ans *= base;
}
if (exponent < 0) {
// For negative exponent, must invert
ans = 1.0 / ans;
}
} else {
// exponent is 0
ans = 1;
}
return ans;
}
If there are no performance constraints you can do:
double x1=1;
for(int i=1;i<=numPowersOf2;i++){
x1 =* 2
}
You can try to do this based on this explanation:
public double myPow(double x, int n) {
if(n < 0) {
if(n == Integer.MIN_VALUE) {
n = (n+1)*(-1);
return 1.0/(myPow(x*x, n));
}
n = n*(-1);
return (double)1.0/myPow(x, n);
}
double y = 1;
while(n > 0) {
if(n%2 == 0) {
x = x*x;
}
else {
y = y*x;
x = x*x;
}
n = n/2;
}
return y;
}
It's unclear whether your comment about using a loop is a desire or a requirement. If it's just a desire there is a math identity you can use that doesn't rely on Math.Pow.
xy = ey∙ln(x)
In Java this would look like
public static double myPow(double x, double y){
return Math.exp(y*Math.log(x));
}
If you really need a loop, you can use something like the following
public static double myPow(double b, int e) {
if (e < 0) {
b = 1 / b;
e = -e;
}
double pow = 1.0;
double intermediate = b;
boolean fin = false;
while (e != 0) {
if (e % 2 == 0) {
intermediate *= intermediate;
fin = true;
} else {
pow *= intermediate;
intermediate = b;
fin = false;
}
e >>= 1;
}
return pow * (fin ? intermediate : 1.0);
}
// Set the variables
int numPowersOf2; //How many powers of 2 to compute
int nextPowerOf2 = 1; //Current power of 2
int exponent = 0;
/* User input here */
// Loop and print results
do
{
System.out.println ("2^" + exponent + " = " + nextPowerOf2);
nextPowerOf2 = nextPowerOf2*2;
exponent ++;
}
while (exponent < numPowersOf2);
here is how I managed without using "myPow(x,n)", but by making use of "while". (I've only been learning Java for 2 weeks so excuse, if the code is a bit lumpy :)
String base ="";
String exp ="";
BufferedReader value = new BufferedReader (new InputStreamReader(System.in));
try {System.out.print("enter the base number: ");
base = value.readLine();
System.out.print("enter the exponent: ");
exp = value.readLine(); }
catch(IOException e){System.out.print("error");}
int x = Integer.valueOf(base);
int n = Integer.valueOf(exp);
int y=x;
int m=1;
while(m<n+1) {
System.out.println(x+"^"+m+"= "+y);
y=y*x;
m++;
}
To implement pow function without using built-in Math.pow(), we can use the below recursive way to implement it. To optimize the runtime, we can store the result of power(a, b/2) and reuse it depending on the number of times is even or odd.
static float power(float a, int b)
{
float temp;
if( b == 0)
return 1;
temp = power(a, b/2);
// if even times
if (b%2 == 0)
return temp*temp;
else // if odd times
{
if(b > 0)
return a * temp * temp;
else // if negetive i.e. 3 ^ (-2)
return (temp * temp) / a;
}
}
I know this answer is very late, but there's a very simple solution you can use if you are allowed to have variables that store the base and the exponent.
public class trythis {
public static void main(String[] args) {
int b = 2;
int p = 5;
int r = 1;
for (int i = 1; i <= p; i++) {
r *= b;
}
System.out.println(r);
}
}
This will work with positive and negative bases, but not with negative powers.
To get the exponential value without using Math.pow() you can use a loop:
As long as the count is less than b (your power), your loop will have an
additional "* a" to it. Mathematically, it is the same as having a Math.pow()
while (count <=b){
a= a* a;
}
Try this simple code:
public static int exponent(int base, int power) {
int answer = 1;
for(int i = 0; i < power; i++) {
answer *= base;
}
return answer;
}

adding fractions using recursion e=1+1/1!+1/2!+1/3!+

I need to write a recursive method to compute the following series:
e = 1+1/1!+1/2!+1/3!+...
This is what I have so far.
public static void main(String[] args)
{ System.out.println("enter n :");
int n =scan.nextInt();
double h = fact(n);
System.out.println(" e = ");
}
public double fact(int n)
{
if (n == 1)
return 1;
else
return ???;
}
}
So, assuming the n input you're taking is the starting denominator for the smallest fraction you'd add...
(For example, given n = 10, you want to add 1 through 1/10)
Then you need to set up your method so that when you call fact(10), it's going to return the sum of 1/10 plus the result of fact(9), or more generically, 1/n + fact(1/n-1);
So, you're looking for something like this:
public double fact(int n) {
if (n < 0) {
return 0.0;
} else if (n == 0) {
return 1.0;
} else {
return (1.0/n + fact(n-1))
}
}
Also, please note the changes to the base cases. When n < 0, we just return 0.0, because if I recall correctly, the factorial of any negative number is always 0, right?
Meanwhile, the base case should be n==0, not n == 1. Your series starts with 1 + 1/1. Note that 1 is not 1/0 or 1/nothing, it's just 1/1. We can't return 1/n when n is 0. For the series to calculate correctly, we have to add the first return the first element of the series in the case of n = 0.
And keep in mind, as with all recursive functions, very large values of n will cause a stack overflow.
Here are a couple of resources:
Math is fun
"Yes you can! But you need to get into a subject called the "Gamma
Function", which is beyond this simple page.
Half Factorial
But I can tell you the factorial of half (½) is half of the square
root of pi = (½)√π, and so some "half-integer" factorials are:"
More specifically you want the Gamma Function
Apache commons has an implementation of this function.
Discussion on Math Exchange
And here is an implementation from Princeton
public class Gamma {
static double logGamma(double x) {
double tmp = (x - 0.5) * Math.log(x + 4.5) - (x + 4.5);
double ser = 1.0 + 76.18009173 / (x + 0) - 86.50532033 / (x + 1)
+ 24.01409822 / (x + 2) - 1.231739516 / (x + 3)
+ 0.00120858003 / (x + 4) - 0.00000536382 / (x + 5);
return tmp + Math.log(ser * Math.sqrt(2 * Math.PI));
}
static double gamma(double x) { return Math.exp(logGamma(x)); }
public static void main(String[] args) {
double x = Double.parseDouble(args[0]);
System.out.println("Gamma(" + x + ") = " + gamma(x));
System.out.println("log Gamma(" + x + ") = " + logGamma(x));
}
}
Calculating e^n recursively is very expensive. It is O(n^2) and it is hard to know when to stop. Instead I suggest you do it iteratively.
static final int runs = 20000;
static volatile int exp = 1;
static volatile int n = 18;
static volatile double dontOptimiseAway;
public static void main(String[] args) throws InterruptedException {
System.out.println("Math.exp(1)=" + Math.exp(1));
System.out.println("exp_iter(18)=" + exp_iter(18));
System.out.println("exp_recurse(18)=" + exp_recurse(18));
for (int t = 0; t < 3; t++) {
System.out.printf("exp(1), exp_iter(18), exp_recurse(18) took %,d / %,d / %,d ns on average%n",
timeMathExp(), timeExpIter(), timeExpRecurse());
}
}
public static long timeMathExp() {
long start = System.nanoTime();
for (int i = 0; i < runs; i++)
dontOptimiseAway = Math.exp(exp);
return (System.nanoTime() - start) / runs;
}
public static long timeExpIter() {
long start = System.nanoTime();
for (int i = 0; i < runs; i++)
dontOptimiseAway = exp_iter(n);
return (System.nanoTime() - start) / runs;
}
public static long timeExpRecurse() {
long start = System.nanoTime();
for (int i = 0; i < runs; i++)
dontOptimiseAway = exp_recurse(n);
return (System.nanoTime() - start) / runs;
}
public static double exp_iter(int n) {
double exp = 0, x = 1;
for (int i = 2; i <= n; i++)
exp += (x /= i);
return 2 + exp;
}
public static double exp_recurse(int n) {
return n <= 0 ? 1 : 1.0 / fact(n) + exp_recurse(n - 1);
}
public static double fact(int n) {
return n <= 1 ? 1 : n * fact(n - 1);
}
prints
Math.exp(1)=2.718281828459045
exp_iter(18)=2.718281828459045
exp_recurse(18)=2.7182818284590455
exp(1), exp_iter(18), exp_recurse(18) took 111 / 191 / 760 ns on average
exp(1), exp_iter(18), exp_recurse(18) took 75 / 78 / 558 ns on average
exp(1), exp_iter(18), exp_recurse(18) took 69 / 66 / 552 ns on average
write the code as below and call it from main class.
public static double recursiveFun(double value){
if (value==1)
return 1.0;
if (value==2){
return (1/(value-1) + 1/value);
}
else
return recursiveFun(value-1) + 1/value;
}

Categories