2017-01-23 5 views
-1

В моем классе я попытался вернуть сумму: 2^n + 2^(n+1) + 2^(n+2) ... двумя способами. Итеративный в первом методе и рекурсивный во втором.Различные результаты аналогичных методов

Это работало до тех пор, пока цифры не были слишком большими. Может ли кто-нибудь объяснить мне, почему эти методы возвращают разные ответы при использовании с большими номерами? И я также хочу знать, какой из них всегда дает правильный ответ.

public class Power 
{ 
    public static void main(String[] args) 
    {  
     System.out.println(iterativ(3)); 
     System.out.println(rekursiv(3)); 

     System.out.println(iterativ(40)); 
     // The recursive one is lower by 10 
     System.out.println(rekursiv(40)); 
    } 

    public static int iterativ(int x) 
    { 
     int sum = 0; 
     for (int i = 0; i <= x; i++) { 
      sum += Math.pow(2, i); 
     } 
     return sum; 
    } 

    public static int rekursiv(int x) 
    {   
     if (x > 0) { 
      return ((int) Math.pow(2, x) + rekursiv(x - 1)); 
     } 
     return 1; 
    } 
} 
+2

«И я также хочу знать, какой из них дает мне правильный ответ». - Я бы предположил, что это ваша работа;) - Изменить: просто видел, что ваш код в основном содержит пример, который я попросил. – Thomas

+0

Отладчик и 'println()' s - ваши лучшие друзья здесь! – alex

+1

Попробуйте использовать код 'double' вместо' int' по крайней мере по одной очевидной причине: максимальное значение для 'int' составляет 2^31-1, что явно ниже 2^40, которое вы пытаетесь сделать. Таким образом, вы получите переполнение с помощью 'int'. 'double' может по-прежнему представлять эти значения, хотя и с некоторой потерей точности. В качестве альтернативы используйте 'long', который допускает значения до 2^63-1 (т. Е. Ваш код должен работать до x = 62). – Thomas

ответ

2

Вы используете функции, которые имеют отношение к double. Вы отбрасываете свои значения до int. Значения каста рано или поздно всегда приводят к некоторым неточным результатам, тем более, если вы отбрасываете от double до int.

Номер, который вы видели при использовании 40 в качестве показателя, был 2147483647, что на самом деле Integer.MAX_VALUE, но не 2^40. Это скорее 2^31-1. В учебнике java есть глава о the primitive datatypes, которая показывает диапазоны каждого типа.

Кроме того, используя double, вы также можете посмотреть на BigDecimal.

Смежные вопросы