2016-12-06 16 views

ответ

0

Ripped от Google:

What is floating point error? 
The most common situation is illustrated by the decimal number 0.1. 
Although it has a finite decimal representation, in binary it has an 
infinite repeating representation. Thus when = 2, the number 0.1 lies 
strictly between two floating-point numbers and is exactly representable 
by neither of them. 

Таким образом, заполнение в вашем примере 9, ваш цикл, вероятно, выглядел как:

num = 0; add 0.0001 -> num is now 0.000099999999 
add 0.0001 -> num is now 0.000199999999998 
add 0.0001 -> num is now 0.000299999999997 
etc... 
add 0.0001 -> num is now 2.9999999999953667 
add 0.0001 -> num is now 3.000099999994321 

И так, ваше точное сравнение 3 не будет соответствовать.

3

Вы не собираетесь, чтобы получить точное равенство. Возможно, вы можете получить в пределах 0.0001 истинного квадратного корня, но это все. Но num*num не будет точно равняться this.first, если только это не квадрат кратного 0.0001.

while ((num * num) < this.first), вероятно, будет ближе к тому, что вы хотите.

+0

Я пробовал запустить его с 9 и не получил выход, почему не num стало 3 и вывести его? –

+1

Можете ли вы предоставить полный метод/класс? – dcsohl

+0

Вероятно, он не работал должным образом из-за того, как десятичные числа с плавающей запятой закодированы в двоичные файлы. У него часто возникают проблемы, подобные этому. Использование '=' для их сравнения не гарантируется на 100%. Вместо этого вам нужно сравнить разницу. Что-то вроде while (abs (this.first - (num * num))> 0.0001) {...}. Кроме того, я надеюсь, что это первый проход, и вы придумаете лучший алгоритм. Это можно было бы взять навсегда, если бы вы захотели придумать sqrt 1 000 000. – Jamie

1

Используйте это:

public class FindSqrt { 

public static void main(String[] strings) { 

    double num = 3; 
    System.out.println(sqrt(num, 0, num)); 
} 


private static double sqrt(double num, double min, double max) { 
    if (max-min<=0.0002) min=max; 
    double middle = (min + max)/2; 
    double x = middle * middle; 
    if ((num>=x&&num-x<=0.02)||(x>=num&&x-num<=0.02)) { 
     return middle; 
    } else if (x < num) { 
     return sqrt(num, middle, max); 
    } else { 
     return sqrt(num, min, middle); 
    } 
} 
} 

Если вам нужно решение без рекурсии (но в то время как петли ОК, следующие работы):

public class FindSqrt { 

public static void main(String[] strings) { 

    double num = 131072; 
    System.out.println(sqrt(num, 0, num)); 
} 


private static double sqrt(double num, double min, double max) { 
    boolean done = false; 
    double answer = 0; 

    while(!done){ 
     if (max-min<=0.0002) min=max; 
     double middle = (min + max)/2; 
     double x = middle * middle; 
     if ((num>=x&&num-x<=0.02)||(x>=num&&x-num<=0.02)) { 
      done = true; 
      answer = middle; 
     } else if (x < num) { 
      min = middle; 
     } else { 
      max = middle; 
     } 
    } 
    return answer; 



} 
} 

Однако, в любом случае, вы можете использовать это найти квадратный корень из чисел < = 131072

+0

Использование рекурсии для решения этой проблемы - плохая идея, учитывая, что max double находится где-то около 1.7 * 10^308. – Jamie

+1

Только если вы используете достаточно большие цифры. Я пошел с предположением (поскольку встроенные библиотеки Math не разрешены), это школьное задание. Вы бы не тестировали его со значениями вне целочисленного диапазона (опять же, предположение). Однако я согласен с тем, что в целом рекурсия будет плохой идеей, просто не в этом конкретном случае. –

+1

@Jamie Я отредактировал свой ответ, чтобы удалить рекурсию. –