Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблема с точностью 
V
    Опции темы
Ares4322
Дата 3.9.2011, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 339
Регистрация: 25.9.2007
Где: Россия, Москва

Репутация: нет
Всего: 3



Доброго времени суток!
Есть программа. Она должна выводить число с точностью 10 знаков после запятой. Но для 100000 циклов она выводит inf. 
Что за inf т как сделать, чтобы она выводила в итоге число с точностью 10 знаков после запятой?
Код

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(int argc, char** argv) {
    int i;
    long double s=0;
    for( i=1; i<100000; i++ ){
        s += powl((i*i),-1);
    }
    printf("%11.10lf\n", s);
    return (EXIT_SUCCESS);
}


PM MAIL   Вверх
boostcoder
Дата 3.9.2011, 12:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 20
Всего: 110



Цитата(Ares4322 @  3.9.2011,  12:49 Найти цитируемый пост)
как сделать, чтобы она выводила в итоге число с точностью 10 знаков после запятой?

использовать GMP ;)
вы наверное не знаете, что при использовании double, на другой платформе/ОС вы получите немного(а может и много) другой результат ;)
PM WWW   Вверх
Ares4322
Дата 3.9.2011, 13:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 339
Регистрация: 25.9.2007
Где: Россия, Москва

Репутация: нет
Всего: 3



Я поясню. Решаю сейчас задачи из учебника на точность. И там такой код:
Код

   int i;
    double s=0;
    for( i=1; i<1000000; i++ ){
        s += 1/(i*i);
    }
    printf("%f\n", s);

По заданию его нужно исправить, чтобы он выводил значение s += 1/(i*i) от 1 до 10000 с точностью до 10 знаков после запятой. Этот код выводит inf. Я его переделал в вышепредставленный. Он тоже выводит  inf. И я не могу понять, как мне выполнить задание.
PM MAIL   Вверх
boostcoder
Дата 3.9.2011, 13:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 20
Всего: 110



ааа, понял)
PM WWW   Вверх
Ares4322
Дата 3.9.2011, 13:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 339
Регистрация: 25.9.2007
Где: Россия, Москва

Репутация: нет
Всего: 3



И все-таки, не подскажете, где ошибка и как решить задачу?
PM MAIL   Вверх
rodnover
Дата 3.9.2011, 13:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 223
Регистрация: 7.4.2009

Репутация: 2
Всего: 10



http://ru.wikipedia.org/wiki/%D0%A1%D1%83%...%8F%D0%B4%D0%B0

user posted image

Оно? 

----
А не. сейчас. 

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

Это сообщение отредактировал(а) rodnover - 3.9.2011, 14:27
PM MAIL   Вверх
Void
Дата 3.9.2011, 14:58 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 2
Всего: 173



Цитата(Ares4322 @  3.9.2011,  14:49 Найти цитируемый пост)
for( i=1; i<100000; i++ ){

Цитата(Ares4322 @  3.9.2011,  15:03 Найти цитируемый пост)
for( i=1; i<1000000; i++ ){

Цитата(Ares4322 @  3.9.2011,  15:03 Найти цитируемый пост)
от 1 до 10000

Определитесь уже. В первом и втором случае переполнение 32-битного int в i * i.



--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
volatile
Дата 3.9.2011, 15:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 16
Всего: 85



Код

    for( i=1; i<1000000; i++ )
    {
        s += 1/(double(i)*i);
    }
    printf("%.10f\n", s);

PM MAIL   Вверх
Фантом
Дата 3.9.2011, 15:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вы это прекратите!
***


Профиль
Группа: Участник Клуба
Сообщений: 1516
Регистрация: 23.3.2008

Репутация: 4
Всего: 49



Что-то Вы странное наворотили. Во-первых, для точности 10 в знаков типа double вполне достаточно. Во-вторых, не надо пользоваться powl(), результат достигается намного проще:
Код

s += 1.0/i/i;

(но именно так - 1.0 нужно для смены типа, (i*i) нельзя, чтобы не вылезти за пределы int).

В принципе, для вящей правильности следовало бы поменять порядок суммирования (от больших i к меньшим), но поскольку запас точности double - еще порядков пять лишних, в данном случае это ни на чем не скажется.

P.S. Про "странное" - это к исходному сообщению, а не к предыдущему.  smile 

Это сообщение отредактировал(а) Фантом - 3.9.2011, 15:56
PM   Вверх
Skevalt
Дата 3.9.2011, 16:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 30.11.2006

Репутация: нет
Всего: 3



Цитата(Фантом @  3.9.2011,  15:54 Найти цитируемый пост)
(но именно так - 1.0 нужно для смены типа, (i*i) нельзя, чтобы не вылезти за пределы int).
 Вы правы, но mingw и liveworkspace корректно обрабатывают и 1.0/(i*i):
Код

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(int argc, char** argv) 
{
    double s = 0.0;
    for(int i = 1; i < 10000; i++)
    {
        s += 1.0/(i*i);
    }
    printf("\n%e", s);
   
    return 0;
}


PM MAIL   Вверх
volatile
Дата 3.9.2011, 16:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 16
Всего: 85



Цитата(Skevalt @  3.9.2011,  16:08 Найти цитируемый пост)
mingw и liveworkspace корректно обрабатывают и 1.0/(i*i):

Но это вовсе не означает что все компиляторы будут корректно обрабатывать данное выражение.
По стандарту порядок вычисления может быть любым. И не исключено что сначала будет высислено (i*i), и произойдет переполнение.

наиболее переносисый код, все-же
Цитата(volatile @  3.9.2011,  15:37 Найти цитируемый пост)
s += 1/(double(i)*i);


PM MAIL   Вверх
Ln78
Дата 4.9.2011, 08:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 274
Регистрация: 25.11.2006

Репутация: нет
Всего: 15



Цитата(Void @  3.9.2011,  14:58 Найти цитируемый пост)
Определитесь уже. В первом и втором случае переполнение 32-битного int в i * i

Приближённо заменим ряд интегралом. Получим, что остаток будет примерно равен 1/N. Так что, если нужно обеспечить точность 10 в минус десятой, то N должно быть не меньше 10 в десятой. Квадрат – 10 в 20-й. А точность даблов – на несколько порядков меньше. Ещё и погрешность суммирования. Таким способом требуемую точность получить не удастся. 


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

Это сообщение отредактировал(а) Ln78 - 4.9.2011, 08:49
PM MAIL   Вверх
mes
Дата 4.9.2011, 10:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(Ln78 @  4.9.2011,  07:45 Найти цитируемый пост)
 А точность даблов – на несколько порядков меньше. 

нужна не "точность расчета", а "точность вывода" :
Цитата(Ares4322 @  3.9.2011,  11:49 Найти цитируемый пост)
 выводить число с точностью 10 знаков




--------------------
PM MAIL WWW   Вверх
Ares4322
Дата 4.9.2011, 11:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 339
Регистрация: 25.9.2007
Где: Россия, Москва

Репутация: нет
Всего: 3



Да, нужна именно точность вывода. 
У меня gcc 4.4.5 и 1/i*i отрабатывает не так, как ожидаешь. В этом и была проблема.
Версии http://forum.vingrad.ru/index.php?showtopi...t&p=2397219 и http://forum.vingrad.ru/index.php?showtopi...t&p=2397221 работают.
Теперь знаю, что порядок вычисления арифметических выражений может быть не таким, каким ты его ожидаешь.
И что желательно явно приводить типы.
Спасибо!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0759 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.