Как написать 1 + 1/2 + 1/3 .... + 1/4999 + 1/5000 в Java? - PullRequest
2 голосов
/ 01 августа 2011

Как написать 1 + 1/2 + 1/3 .... + 1/4999 + 1/5000 в Java?Я пробовал это, но не сработало.

public class Harmonic{
  public static void main(String[] args){
    double sum = 0;
    for(int i=1; i<=5000; i++){
      sum+=1/i;
    }
    System.out.println(sum);
  }
}

Ответы [ 8 ]

16 голосов
/ 01 августа 2011

Добавление чисел от наименьшего к наибольшему будет иметь меньшую погрешность округления.Если вы сравните результат с более высокой точностью, вы увидите, что чем меньше, тем больше.

double sum = 0;
for (int i = 1; i <= 5000; i++) {
    sum += 1.0 / i;
}
System.out.println("From largest to smallest " + sum);

double sum2 = 0;
for (int i = 5000; i >= 1; i--) {
    sum2 += 1.0 / i;
}
System.out.println("From smallest to largest " + sum2);

BigDecimal sum3 = BigDecimal.ZERO;
for (int i = 5000; i >= 1; i--) {
    sum3 = sum3.add(BigDecimal.ONE.divide(BigDecimal.valueOf(i), 30, BigDecimal.ROUND_HALF_UP));
}
System.out.println("BigDecimal               " + sum3);

печатает

From largest to smallest 9.094508852984404
From smallest to largest 9.09450885298443
BigDecimal               9.094508852984436967261245533401
13 голосов
/ 01 августа 2011

1 - это константа типа int, поэтому 1 / (любое целое число больше 1) равно 0. Необходимо указать, что вы хотите разделить числа с плавающей запятой, используя 1.0 (float):

sum+=1.0/i;
      ^
6 голосов
/ 01 августа 2011

Это домашнее задание, тогда я просто помогу вам с подсказкой: будьте осторожны с переменными типами.1/10 равно 0, если мы рассматриваем его как целое число.

4 голосов
/ 01 августа 2011

Попробуйте вместо этого:

sum += 1.0 / i;
3 голосов
/ 01 августа 2011

После первой итерации 1/i всегда будет 0, поскольку это делается в целочисленной арифметике.Таким образом, ваш окончательный ответ будет просто 1. Измените его на 1.0/i, чтобы получить двойную арифметику, и имейте в виду, что после окончания цикла у вас может появиться значительное количество ошибок из-за потери точности при использовании двойных чисел.Вы можете попробовать и посмотреть, насколько это точно.

3 голосов
/ 01 августа 2011

потому что я int, поэтому деление будет усечено ... попробуйте поставить sum+ = 1/(double)i

3 голосов
/ 01 августа 2011

Как насчет:

public class Harmonic{
  public static void main(String[] args){
    double sum = 0;
    for(int i=1; i<=5000; i++){
      sum+=1.0/(double)i;
    }
    System.out.println(sum);
  }
}
0 голосов
/ 13 июня 2016

решение для расчета гармонической суммы:

public static double harmonicSum(int n) {
    return IntStream.rangeClosed(1, n)
                .mapToDouble(i -> (double) 1 / i)
                .sum();
}
...