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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
rotciv
0 / 0 / 0
Регистрация: 04.03.2015
Сообщений: 55
#1

Преобразовать string в complex - C++

28.07.2015, 10:07. Просмотров 588. Ответов 28
Метки нет (Все метки)

Добрый день!

Вот такая простая задачка имеется.
C++
1
2
string S="(1.00000 -2.12363e-09)";
complex cnum;
Требуется избавиться от скобок, а числа поместить в cnum соответственно.

Как бы это поэлегантнее сделать?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.07.2015, 10:07
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Преобразовать string в complex (C++):

Как преобразовать char* в string и вывести переменную string на экран? - C++
for (int k = 0; k < 10; k++) { int x = (int)rand() / RAND_MAX + rand() % 6 + 2; char *chars = new char; ...

Шаблон класса complex. Ошибка undefined reference to `complex<double>::SetRe(double)' - C++
Есть такой файл complex.h #ifndef COMPLEX_H #define COMPLEX_H template&lt;class Type&gt; class complex{ public: Type Re; Type...

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

Преобразовать string в LPBYTE - C++
Подскажите, как это сделать?

Преобразовать string в float - C++
Привет! Подскажите, пожалуйста, наиболее простой способ, как преобразовать значение типа string в float.

Преобразовать string в int .? - C++
строки 66 и 71 соответственно, считываю из файла в string, как преобразовать? кроме static_cast не знаю И по прежнему не понимаю как...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
rotciv
0 / 0 / 0
Регистрация: 04.03.2015
Сообщений: 55
29.07.2015, 09:34  [ТС] #16
Цитата Сообщение от Mr.X Посмотреть сообщение
Я исходил из того, что автор сам данные пишет, а потом сам же их читает, т.е. что данные по умолчанию корректны.
Данные пишет другая программа, проверенная тысячами людей на протяжении десятков лет. В большинстве случаев, данные можно считать корректными.

Число 1.797693134862316e+308 близко к максимальной возможности формата double. Похоже, его принудительно назначили для параметра, не имеющего физической природы. Я вижу в справочниках, что максимальное число - 1.7е+308, и эта величина, возможно, зависит от конкретной платформы.
В программе это число успешно вводится в формате double, но почему-то при преобразовании в complex<double> оно оказывается слишком большим. Можно сделать клиппинг до 1.7е+308, это на конечный результат никак не повлияет.
Цитата Сообщение от Mr.X Посмотреть сообщение
давайте уже поручим автору темы в качестве упражнения самому написать обработку исключений
Давайте попробуем. Но мне для начала надо разобраться с опцией С++11 (похоже, в моем компиляторе это опция -std=c++0x).
Версию 5.1 системщики мне предложили поставить самому в "дом" и пользоваться оттуда. Пока еще с этим разобраться не пытался.
Mr.X
Эксперт С++
3049 / 1694 / 265
Регистрация: 03.05.2010
Сообщений: 3,867
29.07.2015, 10:20 #17
Цитата Сообщение от rotciv Посмотреть сообщение
Число 1.797693134862316e+308 близко к максимальной возможности формата double. Похоже, его принудительно назначили для параметра, не имеющего физической природы. Я вижу в справочниках, что максимальное число - 1.7е+308, и эта величина, возможно, зависит от конкретной платформы.
В программе это число успешно вводится в формате double, но почему-то при преобразовании в complex<double> оно оказывается слишком большим. Можно сделать клиппинг до 1.7е+308, это на конечный результат никак не повлияет.
Ну, на 32-разрядной машине у меня выдает
std::numeric_limits<double>::max() == 1.79769313486231570000e+308
У вас та программа вывела это число с меньшим количеством значащих цифр, из-за чего 157 округлилось до 160, а это уже больше максимума, т.е. число недопустимое.
rotciv
0 / 0 / 0
Регистрация: 04.03.2015
Сообщений: 55
29.07.2015, 11:17  [ТС] #18
Моя 64-битная, похоже, принципиально не хочет нули выводить.
std::numeric_limits<double>::max()1.7976931348623157081452742373170435679807056752584499659891747680315726078002854e+308
Mr.X
Эксперт С++
3049 / 1694 / 265
Регистрация: 03.05.2010
Сообщений: 3,867
29.07.2015, 11:50 #19
Цитата Сообщение от rotciv Посмотреть сообщение
Моя 64-битная, похоже, принципиально не хочет нули выводить.
std::numeric_limits<double>::max()1.7976931348623157081452742373170435679807056752584499659891747680315726078002854e+308
Ну, если setprecision побольше поставите, то выведет. Мораль сей басни - что это значение не стоит использовать как специальное. Может быть проще взять 1e+308 ?
rotciv
0 / 0 / 0
Регистрация: 04.03.2015
Сообщений: 55
29.07.2015, 13:33  [ТС] #20
Я и так уже 80 поставил, что находится за гранью разумного.
Насколько я понимаю, 32- или 64-битность влияет только на адрес, формат double при этом остается неизменным.

1е+308 - можно взять, это ни на что не повлияет в данном случае.

Добавлено через 1 час 11 минут
С опцией std=c++0x скомпилировалось.
Mr.X, я немного переделал ваш пример.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
T_complex   str_to_compl( T_str     s )
{
    T_complex   c;
    auto        ind     =   s.find('(');
 
    try
    {
        s   =   s.substr( ind + 1 );
        c.real  (   stod( s,                &ind    )   );
    }
    catch(...)
    {
      cout<<"Out of range real!\n";
      return 1e+308;
    }
    try
    {
        c.imag  (   stod( s.substr( ind )           )   );
    }
    catch(...)
    {
      cout<<"Out of range imag!\n";
      return 1e+308;
    }
 
    return  c;
}
Не все тут в порядке.
Если я даю на вход строку (1.797693134862316e+308, 1.797693134862316e+308), то только первый блок try catch срабатывает, и результат получается (1е+308, 0)
Avazart
Эксперт С++
7148 / 5325 / 276
Регистрация: 10.12.2010
Сообщений: 23,566
Записей в блоге: 17
29.07.2015, 13:51 #21
Цитата Сообщение от rotciv Посмотреть сообщение
Число 1.797693134862316e+308 близко к максимальной возможности формата double.
Можно попробовать использовать std::complex<> вместе с MPIR,MPFR

Добавлено через 54 секунды
Цитата Сообщение от rotciv Посмотреть сообщение
Давайте попробуем. Но мне для начала надо разобраться с опцией С++11 (похоже, в моем компиляторе это опция -std=c++0x).
Я вроде как указал какая опция вам нужна.
rotciv
0 / 0 / 0
Регистрация: 04.03.2015
Сообщений: 55
29.07.2015, 16:49  [ТС] #22
В общем, я к такому решению в результате пришел.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
         
          string temp, x, x2;  // x, x2 содержат real и imag части комплексного числа
          stringstream ss;
          double real, imag;
...
          temp=x+", "+x2;
          SS_RESET
          ss<<temp;
          if(!(ss>>cx)) {
            real=atof(x.c_str());
            if(real>1.7e+308) cx.real(1.7e+308);
            imag=atof(x2.c_str());
            if(imag>1.7e+308) cx.imag(1.7e+308);
          };
На первый взгляд, делает то, что надо.

Avazart, Mr.X, спасибо за помощь!

Добавлено через 5 минут
Цитата Сообщение от Avazart Посмотреть сообщение
Я вроде как указал какая опция вам нужна.
Не принимает эту опцию.
cc1plus: error: unrecognized command line option "-std=c++11"
Avazart
Эксперт С++
7148 / 5325 / 276
Регистрация: 10.12.2010
Сообщений: 23,566
Записей в блоге: 17
29.07.2015, 17:32 #23
Тогда стоит произвести обновление.
Mr.X
Эксперт С++
3049 / 1694 / 265
Регистрация: 03.05.2010
Сообщений: 3,867
29.07.2015, 18:42 #24
Вот так нормально работает:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <complex>
#include <iostream>
#include <sstream>
#include <string>
/////////////////////////////////////////////////////////////////////////////////////////
typedef std::string                 T_str;
typedef std::complex< double    >   T_complex;
/////////////////////////////////////////////////////////////////////////////////////////
T_complex   str_to_compl( T_str     const   &   s )
{
    static  const   double  EMPTY_VAL     =   1e+308;
 
    T_complex   c   (
                        EMPTY_VAL,
                        EMPTY_VAL
                    );
 
    auto        ind     =   s.find('(');
 
    std::istringstream  ssin
        (
            s.substr( ind + 1 )
        );
 
    T_str   real_str;
    ssin    >>  real_str;
    try
    {
        c.real  (
                    stod( real_str )
                );
    }
    catch(...)
    {}
 
    T_str   imag_str;
    ssin    >>  imag_str;
    try
    {
        c.imag  (
                    stod( imag_str )
                );
    }
    catch(...)
    {}
 
    return  c;
}
/////////////////////////////////////////////////////////////////////////////////////////
int     main()
{
    for(;;)
    {
        std::cout   <<  "compl_str = ";
 
        T_str   s;
        getline( std::cin, s );
 
        std::cout   <<  str_to_compl(s)
                    <<  std::endl
                    <<  std::endl
                    <<  std::endl;
    }//for
}
rotciv
0 / 0 / 0
Регистрация: 04.03.2015
Сообщений: 55
31.07.2015, 11:22  [ТС] #25
Спасибо.

Касательно большого числа - похоже, это значение float и double интерпретируется как NAN (Not a Number).
В этом смысле, присвоение меньшего значения (1.7е+308) не совсем правильно. Потому что величина становится Number, хоть и очень большой.
Avazart
Эксперт С++
7148 / 5325 / 276
Регистрация: 10.12.2010
Сообщений: 23,566
Записей в блоге: 17
31.07.2015, 11:24 #26
Цитата Сообщение от rotciv Посмотреть сообщение
не совсем правильно.
Не правильно выходить за пределы размера типа.
rotciv
0 / 0 / 0
Регистрация: 04.03.2015
Сообщений: 55
31.07.2015, 11:28  [ТС] #27
Думаю, в этом случае следует сделать обход обработки числа, поскольку преобразовывать NaN в комплексное не имеет никакого смысла.
Mr.X
Эксперт С++
3049 / 1694 / 265
Регистрация: 03.05.2010
Сообщений: 3,867
31.07.2015, 12:22 #28
Цитата Сообщение от rotciv Посмотреть сообщение
похоже, это значение float и double интерпретируется как NAN (Not a Number).
Что-то вы меня совсем запутали. NAN так и выводится NAN. Вы же приводили только одно число, которое не обрабатывалось – double max. Откуда флоаты и наны взялись?
Похоже, мы с вами умудрились решить задачу так и не узнав ее точной формулировки. Если руководствоваться моей подписью, то это настоящее проектирование и есть.
rotciv
0 / 0 / 0
Регистрация: 04.03.2015
Сообщений: 55
31.07.2015, 16:56  [ТС] #29
Формулировка общей задачи - не секрет, но я затрудняюсь это изложить в сжатой форме.

Программа, которую я пишу, должна читать данные, записанные программой Cadence Spectre в формате psfascii.
Иногда среди данных встречаются NaNы.
Spectre написан на C/C++, но почему-то в формате psfascii NaN не выводится как NaN, а в виде как я писал выше.
Возможно, причина - в том, что эта часть кода написана давно (возможно, после 90-х ее вообще не трогали, и это - точно С, а не С++).

Когда я просматриваю данные с помощью других программ, входящих в пакет, вижу NaN.

Есть мысль указать спецификацию формата "%20.16g", возможно тогда округлений удастся избежать, и проблема уйдет сама собой.

Добавлено через 3 часа 54 минуты
Цитата Сообщение от rotciv Посмотреть сообщение
Есть мысль указать спецификацию формата "%20.16g",
Даже "%24.17g". Это помогло, проблема ушла.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
31.07.2015, 16:56
Привет! Вот еще темы с ответами:

Преобразовать int в string - C++
Как перевести переменную int в string?

Преобразовать string^ в double - C++
Есть старая программа на c++, написанная в среде MS VS2010 с использование WinForm, и, как следствие .Net Появилась проблема с...

Преобразовать string в TCHAR - C++
Подскажите пожалуйста в чем ошибка. Нужно преобразовать string -&gt; TCHAR взял из поста string to TCHAR выдает ошибку d:\program...

Преобразовать из float в string - C++
Скажите, пжл, какие существуют ф-ии для конвертации из float в string?


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
31.07.2015, 16:56
Ответ Создать тему
Опции темы

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