Форум программистов, компьютерный форум CyberForum.ru

C++

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 106, средняя оценка - 4.87
YuliLa
4 / 4 / 0
Регистрация: 15.10.2010
Сообщений: 71
#1

Вещественные числа с плавающей точкой, точность вычислений - C++

07.06.2012, 12:31. Просмотров 13406. Ответов 70
Метки нет (Все метки)

Работаю над проектом, требующим большую точность вычисления вещественных чисел.
Решила использовать long double в надежде получить точность побольше.
Столкнулась с тем, что C++ Builder просто отказывается давать желаемую точность.
Точность необходима до 10^20. То есть до 20 числа после запятой.
Подскажите пожалуйста как решить данную проблему.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.06.2012, 12:31     Вещественные числа с плавающей точкой, точность вычислений
Посмотрите здесь:
Точность числа с плавающей точкой C++
Конструирование значения целого числа или числа с плавающей точкой по его дампу C++
Усечение числа с плавающей точкой C++
C++ Вывод числа с плавающей точкой
Округлить числа с плавающей точкой C++
C++ Неправильный вывод числа с плавающей точкой
C++ WinAPI Чтение из EDIT числа с плавающей точкой
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Avazart
Эксперт С++
7115 / 5292 / 273
Регистрация: 10.12.2010
Сообщений: 23,387
Записей в блоге: 17
08.06.2012, 13:12     Вещественные числа с плавающей точкой, точность вычислений #21
Что именно у тебя работает?
Ну число 10^-25 не воспринимается как 0 и ошибки нет.
Evg
Эксперт CАвтор FAQ
17533 / 5771 / 369
Регистрация: 30.03.2009
Сообщений: 15,872
Записей в блоге: 26
08.06.2012, 16:01     Вещественные числа с плавающей точкой, точность вычислений #22
Цитата Сообщение от Avazart Посмотреть сообщение
Ну число 10^-25 не воспринимается как 0 и ошибки нет.
А ты распечатай число 1.000...001 (т.е. 1 + 10^-25), сразу увидишь проблему

Именно этот параметр и есть машинное эпислон
Avazart
Эксперт С++
7115 / 5292 / 273
Регистрация: 10.12.2010
Сообщений: 23,387
Записей в блоге: 17
08.06.2012, 17:29     Вещественные числа с плавающей точкой, точность вычислений #23
А ты распечатай число 1.000...001 (т.е. 1 + 10^-25), сразу увидишь проблему
Пример кода можно?
Evg
Эксперт CАвтор FAQ
17533 / 5771 / 369
Регистрация: 30.03.2009
Сообщений: 15,872
Записей в блоге: 26
08.06.2012, 17:39     Вещественные числа с плавающей точкой, точность вычислений #24
C
1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
 
int main (void)
{
  long double ld1 = 1L + 1e-19L;
  long double ld2 = 1L + 1e-20L;
 
  printf ("ld1=%.25Lf\n", ld1);
  printf ("ld2=%.25Lf\n", ld2);
  return 0;
}
Код
$ gcc t.c
$ ./a.out
ld1=1.0000000000000000001084202  <--- отличается от 1.0
ld2=1.0000000000000000000000000  <--- совпадает с 1.0
Avazart
Эксперт С++
7115 / 5292 / 273
Регистрация: 10.12.2010
Сообщений: 23,387
Записей в блоге: 17
08.06.2012, 17:55     Вещественные числа с плавающей точкой, точность вычислений #25
Ага понял...

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int _tmain(int argc, _TCHAR* argv[])
{
system("chcp 1251");
 
  long double ld1 = 1L + 1e-19L;
  long double ld2 = 1L + 1e-20L;
 
  printf ("ld1=%.25Lf\n", ld1);
  printf ("ld2=%.25Lf\n", ld2);
 
  printf ("ld2=%.25Lf\n",ld2-1.);
 
system("pause");
return 0;
}
Код
Текущая кодовая страница: 1251
ld1=1.0000000000000000001000000
ld2=1.0000000000000000000000000
dif=0.0000000000000000000000000
Для продолжения нажмите любую клавишу . . .
Добавлено через 7 минут
Но тогда проблема в вычислении самих чисел а не логарифма их разности.
Т.е как они вычилсяются?
Avazart
Эксперт С++
7115 / 5292 / 273
Регистрация: 10.12.2010
Сообщений: 23,387
Записей в блоге: 17
08.06.2012, 18:01     Вещественные числа с плавающей точкой, точность вычислений #26
Чет запутался как тогда на VS работает если там уже первое число не отличается?
Миниатюры
Вещественные числа с плавающей точкой, точность вычислений  
Evg
Эксперт CАвтор FAQ
17533 / 5771 / 369
Регистрация: 30.03.2009
Сообщений: 15,872
Записей в блоге: 26
08.06.2012, 18:23     Вещественные числа с плавающей точкой, точность вычислений #27
Цитата Сообщение от Avazart Посмотреть сообщение
Но тогда проблема в вычислении самих чисел а не логарифма их разности
Ну это целый паровоз проблем, которые зацепляются одна за другую. Сначала делается разность двух чисел, которые очень мало отличаются и эта разность становится либо равной нулю, либо вычисляется с очень большой погрешностью

Цитата Сообщение от Avazart Посмотреть сообщение
Чет запутался как тогда на VS работает если там уже первое число не отличается?
Чему равен sizeof (long double)? Ну и попробуй поиграть порядком. Не -19, а -15 и т.п.
Avazart
Эксперт С++
7115 / 5292 / 273
Регистрация: 10.12.2010
Сообщений: 23,387
Записей в блоге: 17
08.06.2012, 19:08     Вещественные числа с плавающей точкой, точность вычислений #28
Чему равен sizeof (long double)?
На Builder2009 - 10, на VS2010- 8...

Добавлено через 3 минуты
Сначала делается разность двух чисел
Да нет проблема у еще раньше когда числам присваиваются числа врезудьтате чего они "обрезаются"...

Поэтому вопрос в том как вычисляются эти числа и можно ли это обойти как нибудь.
Evg
Эксперт CАвтор FAQ
17533 / 5771 / 369
Регистрация: 30.03.2009
Сообщений: 15,872
Записей в блоге: 26
08.06.2012, 19:15     Вещественные числа с плавающей точкой, точность вычислений #29
Цитата Сообщение от Avazart Посмотреть сообщение
На Builder2009 - 10, на VS2010- 8...
На builder'е правильный long double, на VS2010 - неправильный. Либо это в настройках как-то можно подправить, либо в express edition (если у тебя именно оно) микрософтовцы намерено так сделали. Т.е. сейчас у тебя VS работает как старые компиляторы, т.е. long double эквивалентен double

Цитата Сообщение от Avazart Посмотреть сообщение
Поэтому вопрос в том как вычисляются эти числа и можно ли это обойти как нибудь
Вычисляются согласно стандарту. Для float и double это IEEE-754, для 80-битного long double га intel'е - IEEE-854. В любом случае так работает аппаратура и с этим уже ничего не поделать. Кроме использования специальных библиотек, которые эмулируют ещё бОльшую точность
Avazart
Эксперт С++
7115 / 5292 / 273
Регистрация: 10.12.2010
Сообщений: 23,387
Записей в блоге: 17
08.06.2012, 20:01     Вещественные числа с плавающей точкой, точность вычислений #30
Кроме использования специальных библиотек, которые эмулируют ещё бОльшую точность
Я имел ввиду обойти каким нибудь математичеким путем, например разложением в ряд.

Добавлено через 3 минуты
либо в express edition (если у тебя именно оно) микрософтовцы намерено так сделали.
VS2010 Professional

Добавлено через 38 минут
C++
1
2
xh_1= Prognoz(Nin,xh,h);
xh_h_1=Prognoz(Nin, xh_h,h);
Т.е может как-то ф-цию Prognoz() можно переписать....
Evg
Эксперт CАвтор FAQ
17533 / 5771 / 369
Регистрация: 30.03.2009
Сообщений: 15,872
Записей в блоге: 26
08.06.2012, 22:03     Вещественные числа с плавающей точкой, точность вычислений #31
Цитата Сообщение от Avazart Посмотреть сообщение
Я имел ввиду обойти каким нибудь математичеким путем, например разложением в ряд
Если вопрос в том, как их хранить - то никак. Если нет представления о том, как хранятся плавающие числа - можешь почитать объяснение на пальцах.

Ты можешь хранить два отдельных слагаемых в двух разных переменных: a=1 и b=10^-20. Если потом тебе надо будет вычесть 0.999, то ты это представишь как a=(1 - 0.999) и b=10^-20. По другому никак - формат хранения чисел тебе этого сделать не позволит
Avazart
Эксперт С++
7115 / 5292 / 273
Регистрация: 10.12.2010
Сообщений: 23,387
Записей в блоге: 17
08.06.2012, 22:11     Вещественные числа с плавающей точкой, точность вычислений #32
Ты можешь хранить два отдельных слагаемых в двух разных переменных
Что-то вроде этого я и имел ввиду...
( например если разкладывать в ряд то члены ряда можно хранить в векторе ну это зависит от конкретного случая)
А какие есть библиотеки для таких случаев для С++? А то что-то не нагуглил...
Evg
Эксперт CАвтор FAQ
17533 / 5771 / 369
Регистрация: 30.03.2009
Сообщений: 15,872
Записей в блоге: 26
08.06.2012, 23:35     Вещественные числа с плавающей точкой, точность вычислений #33
Цитата Сообщение от Avazart Посмотреть сообщение
А какие есть библиотеки для таких случаев для С++?
Поискал по "huge float point". Наткнулся на
http://gmplib.org/
http://www.mpfr.org/
http://www.nongnu.org/hpalib/
Avazart
Эксперт С++
7115 / 5292 / 273
Регистрация: 10.12.2010
Сообщений: 23,387
Записей в блоге: 17
08.06.2012, 23:44     Вещественные числа с плавающей точкой, точность вычислений #34
http://axsm.blogspot.com/2010/05/gmp-windows-mingw.html
http://agapii.ucoz.ru/publ/sborka_gm...indows/1-1-0-7

Добавлено через 4 минуты
Тема осталась пуста gmp+builder 6.0
Avazart
Эксперт С++
7115 / 5292 / 273
Регистрация: 10.12.2010
Сообщений: 23,387
Записей в блоге: 17
09.06.2012, 00:38     Вещественные числа с плавающей точкой, точность вычислений #35
Нашел уже скомпилиные либы под некоторые компиляторы http://www.cs.nyu.edu/exact/core/gmp/
Подключить их не под Builder не под Visual не получилось...
Builder на мой взгляд выдает что то критичное ( использовал dll для VC перековертив их в lib)
Миниатюры
Вещественные числа с плавающей точкой, точность вычислений  
Avazart
Эксперт С++
7115 / 5292 / 273
Регистрация: 10.12.2010
Сообщений: 23,387
Записей в блоге: 17
09.06.2012, 00:41     Вещественные числа с плавающей точкой, точность вычислений #36
VC ругается только когда пытаешся использовать код( но возможно что не так сделал)
Миниатюры
Вещественные числа с плавающей точкой, точность вычислений  
Avazart
Эксперт С++
7115 / 5292 / 273
Регистрация: 10.12.2010
Сообщений: 23,387
Записей в блоге: 17
09.06.2012, 00:47     Вещественные числа с плавающей точкой, точность вычислений #37
Еще ссылки
http://www.imach.uran.ru/cbignum/papers/cb2009p.htm
Как подключить gmp lib
YuliLa
4 / 4 / 0
Регистрация: 15.10.2010
Сообщений: 71
09.06.2012, 00:49  [ТС]     Вещественные числа с плавающей точкой, точность вычислений #38
Теперь ещё с этим всем разобраться.
Спасибо!
Avazart
Эксперт С++
7115 / 5292 / 273
Регистрация: 10.12.2010
Сообщений: 23,387
Записей в блоге: 17
09.06.2012, 01:15     Вещественные числа с плавающей точкой, точность вычислений #39
Удалось скомпилить под VC по этим рекомендациям
Я делал под Visual Studio.
Качаете архив gmp-static-vc-4.1.2.zip отсюда. http://www.cs.nyu.edu/exact/core/gmp/
Добавляете файл gmp.h в папку VC/include, а *.lib в VC/lib

Создаете новый ПУСТОЙ проект, пишите любой код на gmp (читайте мануалы, что Вам дали выше).
Например (это выводит 2^100):

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <gmp.h>
 
int main ( ) {
   mpz_t x;      
   mpz_init_set_si(x, 1);
      
   for ( int i = 0; i < 100; i ++ )
      mpz_add ( x, x, x ); 
 
   mpz_out_str ( stdout, 10, x );
 
   return 0;
}
В настройках проекта (Project -> Properties) нужно указать:
C++/Code Generation -> Runtime library = Multi-threaded (/MT)
Linker/Input -> Additional dependences = "gmp.lib" и "libcmt.lib" (без кавычек)
Linker/Input -> Ignore Specific library = libc.lib

Все, после этого у меня все сразу запустилось.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.06.2012, 15:46     Вещественные числа с плавающей точкой, точность вычислений
Еще ссылки по теме:
C++ числа с плавающей точкой после деления
C++ Ifstream считать из файла числа с плавающей точкой
При вводе числа с плавающей точкой завершается программа C++
Отличить целое от числа с плавающей точкой в 32-разрядном регистре C++
Перевод числа с плавающей точкой из шестнадцатиричного в двоичный вид C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Evg
Эксперт CАвтор FAQ
17533 / 5771 / 369
Регистрация: 30.03.2009
Сообщений: 15,872
Записей в блоге: 26
09.06.2012, 15:46     Вещественные числа с плавающей точкой, точность вычислений #40
На всякий случай. Тему переместили и открыли
Yandex
Объявления
09.06.2012, 15:46     Вещественные числа с плавающей точкой, точность вычислений
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru