C точность чисел и усечение с помощью fstream

#c #fstream #truncate #floating-point-precision #digits

#c #fstream #усечение #точность с плавающей запятой #цифры

Вопрос:

У меня есть file.txt с сотнями цифр. У них много цифр (максимум 20) после точки, и мне нужно получить их все без усечения, иначе они вносят ошибки в следующие вычисления. Я сделал эти числа с помощью matlab, поэтому они имеют чудовищную точность, но теперь я должен повторить это поведение в своей программе.

Я сделал это так:

  fstream in;
 in.open(file.txt, ios::in);
 long double number;
 in>>number;
  

Я тоже пробовал это

  in.precision(20);
 in>>number;
  

перед каждой операцией «>>», но это тщетно

Комментарии:

1. Вам не повезло в этом — обычно точность составляет long double всего 18 цифр ( ссылка на демонстрацию, которая показывает вам, как определить точность в вашей собственной системе ).

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

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

4. Вопрос: являются ли значения matlab точными (раньше они могли быть напечатаны с 20 цифрами и низкой точностью)?

5. Следуя мысли @Dieter, тип данных по умолчанию в Matlab обычно 64-разрядный double .

Ответ №1:

std::numeric_limits::min std::numeric_limits::digits10 может сказать вам, для чего нужна фактическая точность вашей цели long double .

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

Комментарии:

1. длинный двойной: 3.3621e-4932 один из моих номеров — 2.7239385667867091 как я могу прочитать все его цифры? если я вставлю это число в свой код, все пойдет хорошо, как в matlab, так что это должна быть проблема функций, а не точности, не так ли?

2. std::numeric_limits::min указывает наименьшее представимое число, а не точность. std::numeric_limits::digits10 указывает точность (т. Е. Максимальное количество значащих цифр).

Ответ №2:

В моей системе (Win7, VS2012) отлично работает следующее:

 #include <fstream>
#include <iostream>

int main (void)
{
    std::ifstream file ("test.txt") ;

    long double d = 0 ;
    file >> d ;

    std::cout.precision (20) ;
    std::cout << d << "n" ;


    return 0 ;
}
  

Текстовый файл:

2.7239385667867091

Вывод:

2.7239385667867091

Если это не работает в вашей системе, вам необходимо использовать стороннюю библиотеку чисел.

Комментарии:

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

2. вычисления будут правильными, если я введу числа вручную. Я думаю, что все из-за этой загрузки

3. @user3290180 Да, существует возможная разница между точностью вывода и точностью вычислений. Ваш отладчик может сообщить вам, есть ли проблема с загрузкой. Возможно, вам следует отредактировать свой вопрос, чтобы показать небольшой краткий пример того, как вычисления не работают. У меня такое чувство, что просмотр ассемблерного кода покажет вам, почему одно правильно, а другое нет.