Вычислить сумму растущих чисел в массиве с плавающей точкой, используя Java - PullRequest
0 голосов
/ 22 января 2012

Я должен написать программу на Java для суммирования следующей последовательности: 1,0 / 1,0 + 1,0 / 2,0 + 1,0 / 3,0 ... + 1,0 / 15 000 000,0 в порядке возрастания, а затем снова в порядке убывания, начиная с 1,0 / 15 000 000,0 + 1,0 / 14 999 999 вплоть до 1,0 / 1,0 с использованием 32-битной плавающей запятой. Я изо всех сил пытаюсь выяснить, как это сделать, но вот что у меня есть (не знаю, сработает ли это):

РЕДАКТИРОВАТЬ: Извините, что снова открыл эту вещь, но я получаю 1,0 для обоих ответов, и я уверен, что это неправильно. Кто-нибудь знает, что я сделал не так?

public class FloatSum {

public static float increasingSum (float numbers1){
float sum1 = 0;
for (int i = 1; i <= 15000000; i++){ 
    sum1 = sum1 + 1/i; 
    } 
return sum1;
} 

public static float decreasingSum (float numbers2){
float sum2 = 0;
for (int i = 15000000; i >= 1; i--){ 
    sum2 = sum2 + 1/i; 
    } 
return sum2;
}

public static void main(String[] args) {
float sum1 = 0;
float sum2 = 0; 

System.out.println(increasingSum(sum1));
System.out.println(increasingSum(sum2));
}
}

Ответы [ 4 ]

5 голосов
/ 22 января 2012

Поскольку это домашняя работа, я ограничу свой ответ парой подсказок:

  1. Вам не нужен массив: достаточно одной скалярной переменной аккумулятора. Инициализируйте его до нуля и добавьте к нему каждый член.
  2. Не зацикливайтесь на членах суммы, зацикливайте на знаменателях (которые очень удобно целочисленные).
2 голосов
/ 22 января 2012

Полностью согласен с AIX. Относительно того, почему ваш код не компилируется: переменная «a» является плавающей точкой, но затем вы пытаетесь использовать ее для доступа к массиву (для которой требуется int), и поскольку использование float в качестве int недопустимо, вы получаете ошибка компиляции. Вы можете исправить ошибку, приведя число с плавающей точкой к int

numbers1[(int)a]

но это будет бесполезно, так как программа все еще не так:

  • нет никакого смысла в доступе к массиву, так как все элементы равны 0 (вы правильно создали массив, но все элементы просто инициализированы в 0)
  • , поскольку условие теста для for равно a < numbers1.length, на последней итерации вы получите ArrayOutOfBoundException в коде numbers1[a+1] (вы попытаетесь получить доступ к 15000001-му элементу)

Есть еще одна проблема, которая не приведет к сбою вашей программы, но, похоже, выявляет некоторое непонимание того, как работает цикл for: в частности, вы увеличиваете переменную x на каждой итерации, но это бесполезно, поскольку переменная x используется только для инициализации: часть a = 1/x выполняется ровно один раз, до выполнения цикла. Вот краткий for учебник для начинающих:

for( Initializer; TestExpr; CountExpr ){ Body }

Машина, которая выполняет цикл, выполнит следующее:

  1. Выполнить код Initializer
  2. если TestExpr оценить до false, перейти к 6
  3. выполнить код Body
  4. выполнить код CountExpr
  5. Перейти к 2
  6. отделка!

Совет, который я могу вам дать, - попытаться на бумаге решить, как выполнить вашу задачу, используя обычные математические конструкции, а затем "перенести" ваше решение в java.

1 голос
/ 22 января 2012

Ваша логика в цикле for неверна. Хаха, я не совсем уверен, что ты говоришь, но давайте посмотрим, сможем ли мы пройти через это ...

Забудьте пока остальную часть кода и сосредоточьтесь на том, что делает цикл for:

Вы инициализируете переменную с плавающей запятой 'a' как 1 / x. Установите конечное значение как длину массива (хорошо). а затем вы увеличиваете переменные «а» на 1 и «х» на 1 ...

Теперь подумайте об этом так, вы инициализируете «a» как 1 / x, делая его 1. Он проходит через цикл со значением a = 1. Затем он увеличивает «x» на 1 и увеличивает «a» на 1. Теперь подумайте, потому что именно здесь ваша логика ошибочна. Это действительно делает x = 2 сейчас, но вы ТАКЖЕ делаете a = 2. «x» и «a» являются независимыми переменными. Перечитайте определение цикла for и посмотрите, сможете ли вы согласовать то, что вы пытаетесь сделать.

Теперь цикл позволяет вам выполнять итерации. В этом случае у вас есть 30 000 000 из них (15 000 000 «считать» и 15 000 000 «считать вниз»). Итак, давайте сделаем два цикла for, каждый с 15 000 000 итераций

for (int i = 1; i <= 15000000; i++){
statements;
}

for (int i = 15000000; i >= 1; i--){
statements;
}

Теперь вы хотите сложить вместе 1,0 / 1,0 + 1,0 / 2,0 + ... + 1,0 / 15 000 000,0. Инициализируйте sum1 в 0:

float sum1 = 0; 

В каждой итерации вы собираетесь добавлять 1 / i к сумме. Таким образом, ваше утверждение внутри каждого цикла for будет выглядеть как

sum1 += 1/i;

что совпадает с

sum1 = sum1 + 1/i;

И вот оно у вас. Для первого цикла каждая итерация добавляет 1 / i, начиная с i = 1 и заканчивая i = 15 000 000. Для второго цикла добавляется 1 / i, начиная с i = 15 000 000 и заканчивая i = 1. Очевидно, в вашем случае вы можете заменить 15 000 000 на «numbers1.length». Затем верните sum1, и все ваши ошибки исчезнут просто так.

примечание: осторожно, как вы ограничиваете цикл for. Убедитесь, что он включает в себя конечные значения. (обратите внимание на <= 15 000 000 и> = 1 в двух циклах) Это не будет иметь большого значения в вашем коде, и ответ будет таким же, но в будущем он будет значительным.

0 голосов
/ 22 января 2012

используйте float, если хотите, но посмотрите на это: Java: почему мы должны использовать BigDecimal вместо Double в реальном мире?

Это называется потеря точности .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...