singlepost

Как вычислить (S0 ∙ … ∙ SN)^1/(N + 1) без переполнения << На главную или назад  

есть цикл
For i=1 to N
и формула
GAT = (S0 ∙ … ∙ SN)^1/(N + 1)
надо её посчитать
если сначала отдельно произведение брать,а потом за циклом степень,выдает переполнение
как степень разложить???

25 ответов в теме “Как вычислить (S0 ∙ … ∙ SN)^1/(N + 1) без переполнения”

  1. 14
    Дмитрий Анисимов ответил:

    Тема для группы "хреновые программисты" ;-)

  2. 13
    Леонид Максимов ответил:

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

    впрочем, если это для диплома, то хватит и написанного выше.

  3. 12
    Жека Кирпичев ответил:

    Вадим, быстрее-то быстрее, но автор говорит, что у него произведение переполняет вещественный тип. Поэтому и приходится извращаться.

  4. 11
    Леонид Максимов ответил:

    что-то не то у вас с кодом. надо примерно так:
    for i=1 to N
    GAT = GAT + Log(S(i-1+LBound(S)))
    Next i
    GAT = Exp(GAT / (N + 1))

    или так (если совсем страшно):
    for i=1 to N
    GAT = GAT + Log(eval("S" & i))
    Next i
    GAT = Exp(GAT / (N + 1))

  5. 10
    Дмитрий Кузнецов ответил:

    сделал =)))
    начальную GAT не првильно задал
    Спасибо!!

  6. 9
    Дмитрий Кузнецов ответил:

    СпаСибо всем,кто откликнулся!!!
    будете смеяться-эту хрень надо реализовать для диплома подруги на VBA под экселем. Уже голову сломал.
    короч
    for i=1 to N
    GAT = GAT + Log(S)
    Next i
    GAT = Exp(GAT / (N + 1))
    не пашет
    может я туплю

  7. 8
    Вадим Проценко ответил:

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

  8. 7
    Офыволдшощзй Фыошщфышщоаргк ответил:

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

  9. 6
    Жека Кирпичев ответил:

    Думаю, идеи пригодятся многим, так что запощу решение и здесь..
    GAT = exp(1/(N+1) * (ln s0 + ln s1 + ln s2 + … + ln sn))
    Если жесткие требования к точности, то логарифмы надо складывать с помощью приоритетной очереди, а в зависимости от того, какого порядка числа S0, .., SN, может существовать более удачное решение, чем то, что я написал.

  10. 5
    Вадим Проценко ответил:

    Примерно так:
    p:=1;
    for i=1 to N do p:=p*s[i];
    GAT:=exp(ln(p)/(N+1));

  11. 4
    Дмитрий Кузнецов ответил:

    идея зачетная,но не пашет
    надо как-то делить расписать

  12. 3
    Дмитрий Кузнецов ответил:

    а как в цикл зафигачить??

  13. 2
    Леонид Максимов ответил:

    суммирование в цикле, а остальное – снаружи

  14. 1
    Леонид Максимов ответил:

    так как все равно берется корень, то тебе поможет вот такая формула:
    (a1*a2)^(1/b) = exp((ln(a1)+ln(a2))/b)

Клуб программистов работает уже ой-ой-ой сколько, а если поточнее, то с 2007 года.