4 / 4 / 0
Регистрация: 15.10.2010
Сообщений: 71
1

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

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

Author24 — интернет-сервис помощи студентам
Работаю над проектом, требующим большую точность вычисления вещественных чисел.
Решила использовать long double в надежде получить точность побольше.
Столкнулась с тем, что C++ Builder просто отказывается давать желаемую точность.
Точность необходима до 10^20. То есть до 20 числа после запятой.
Подскажите пожалуйста как решить данную проблему.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.06.2012, 12:31
Ответы с готовыми решениями:

Точность числа с плавающей точкой
У типа float числа одинарной точности с плавающей запятой обеспечивают относительную точность 7-8...

Максимальная точность для чисел с плавающей точкой
Суть поставленной задачи: дан вектор от 10_000 до 100_000 элементов, нужно проходить по вектору,...

Представить вещественные числа в четырёхбайтовой ячейке памяти в формате с плавающей точкой
Пожалуйста помогите Представить вещественные числа в четырёхбайтовой ячейке памяти в формате с...

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

70
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
08.06.2012, 13:12 21
Author24 — интернет-сервис помощи студентам
Что именно у тебя работает?
Ну число 10^-25 не воспринимается как 0 и ошибки нет.
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
08.06.2012, 16:01 22
Цитата Сообщение от Avazart Посмотреть сообщение
Ну число 10^-25 не воспринимается как 0 и ошибки нет.
А ты распечатай число 1.000...001 (т.е. 1 + 10^-25), сразу увидишь проблему

Именно этот параметр и есть машинное эпислон
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
08.06.2012, 17:29 23
А ты распечатай число 1.000...001 (т.е. 1 + 10^-25), сразу увидишь проблему
Пример кода можно?
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
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
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
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 минут
Но тогда проблема в вычислении самих чисел а не логарифма их разности.
Т.е как они вычилсяются?
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
08.06.2012, 18:01 26
Чет запутался как тогда на VS работает если там уже первое число не отличается?
Миниатюры
Вещественные числа с плавающей точкой, точность вычислений  
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
08.06.2012, 18:23 27
Цитата Сообщение от Avazart Посмотреть сообщение
Но тогда проблема в вычислении самих чисел а не логарифма их разности
Ну это целый паровоз проблем, которые зацепляются одна за другую. Сначала делается разность двух чисел, которые очень мало отличаются и эта разность становится либо равной нулю, либо вычисляется с очень большой погрешностью

Цитата Сообщение от Avazart Посмотреть сообщение
Чет запутался как тогда на VS работает если там уже первое число не отличается?
Чему равен sizeof (long double)? Ну и попробуй поиграть порядком. Не -19, а -15 и т.п.
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
08.06.2012, 19:08 28
Чему равен sizeof (long double)?
На Builder2009 - 10, на VS2010- 8...

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

Поэтому вопрос в том как вычисляются эти числа и можно ли это обойти как нибудь.
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
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. В любом случае так работает аппаратура и с этим уже ничего не поделать. Кроме использования специальных библиотек, которые эмулируют ещё бОльшую точность
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
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() можно переписать....
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
08.06.2012, 22:03 31
Цитата Сообщение от Avazart Посмотреть сообщение
Я имел ввиду обойти каким нибудь математичеким путем, например разложением в ряд
Если вопрос в том, как их хранить - то никак. Если нет представления о том, как хранятся плавающие числа - можешь почитать объяснение на пальцах.

Ты можешь хранить два отдельных слагаемых в двух разных переменных: a=1 и b=10^-20. Если потом тебе надо будет вычесть 0.999, то ты это представишь как a=(1 - 0.999) и b=10^-20. По другому никак - формат хранения чисел тебе этого сделать не позволит
1
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
08.06.2012, 22:11 32
Ты можешь хранить два отдельных слагаемых в двух разных переменных
Что-то вроде этого я и имел ввиду...
( например если разкладывать в ряд то члены ряда можно хранить в векторе ну это зависит от конкретного случая)
А какие есть библиотеки для таких случаев для С++? А то что-то не нагуглил...
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
08.06.2012, 23:35 33
Цитата Сообщение от Avazart Посмотреть сообщение
А какие есть библиотеки для таких случаев для С++?
Поискал по "huge float point". Наткнулся на
http://gmplib.org/
http://www.mpfr.org/
http://www.nongnu.org/hpalib/
2
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
08.06.2012, 23:44 34
http://axsm.blogspot.com/2010/... mingw.html
http://agapii.ucoz.ru/publ/sbo... ws/1-1-0-7

Добавлено через 4 минуты
Тема осталась пуста gmp+builder 6.0
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
09.06.2012, 00:38 35
Нашел уже скомпилиные либы под некоторые компиляторы http://www.cs.nyu.edu/exact/core/gmp/
Подключить их не под Builder не под Visual не получилось...
Builder на мой взгляд выдает что то критичное ( использовал dll для VC перековертив их в lib)
Миниатюры
Вещественные числа с плавающей точкой, точность вычислений  
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
09.06.2012, 00:41 36
VC ругается только когда пытаешся использовать код( но возможно что не так сделал)
Миниатюры
Вещественные числа с плавающей точкой, точность вычислений  
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
09.06.2012, 00:47 37
Еще ссылки
http://www.imach.uran.ru/cbign... b2009p.htm
Как подключить gmp lib
1
4 / 4 / 0
Регистрация: 15.10.2010
Сообщений: 71
09.06.2012, 00:49  [ТС] 38
Теперь ещё с этим всем разобраться.
Спасибо!
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
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

Все, после этого у меня все сразу запустилось.
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
09.06.2012, 15:46 40
На всякий случай. Тему переместили и открыли
0
09.06.2012, 15:46
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.06.2012, 15:46
Помогаю со студенческими работами здесь

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

Точность вычислений в double (Обрезание числа)
Здравствуйте! Дело в том, что мне необходимо выводить большие числа с большим количеством знаков...

Числа с плавающей точкой
Здравствуйте, создаю я, значит, батник. И тут столкнулся с такое проблемой: при присвоении...

Числа с плавающей точкой
Как отделить целую часть и дробную? Например имеем число 12.54 число 12 должно бить записано в...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru