Я попробовал два метода, чтобы преобразовать мой char*
тип ss
на двойной тип.
Вот мой код (скомпилирован в VC ++ 6.0 windows64-bit)
int main()
{
char *ss = "-1964734.544";
cout<<ss<<endl;
cout<<*reinterpret_cast<double*>(ss)<<endl;
cout<<*(double *)ss<<endl;
}
Результаты:
-1964734.544
3.06123e-057
3.06123e-057
Мне не понятно что не так и как конвертировать char*
удвоить.
Ты можешь использовать strtod
как это: double smth=strtod(ss,NULL,10);
Можно использовать немного другой синтаксис. Увидеть этот для примера.
Ваша проблема здесь в том, что АКТЕРЫ — НЕ КОНВЕРСИЯ:
char *ss = "-1964734.544";
cout<<ss<<endl;
cout<<*reinterpret_cast<double*>(ss)<<endl;
cout<<*(double *)ss<<endl;
в том, что вы конвертируете строку символов в число. Это означает, что ваша память содержит числа, являющиеся значениями ascii:
"-1964734.544"
хранится в памяти как:
45, 49, 57, 54, 52, 55, 51, 52, 46, 53, 52, 52
который в двоичном виде становится:
00101101,00110001,00111001,00110110,00110100,00110111,00110011,00110100,00101110,00110101,00110100,00110100
в памяти. При преобразовании в double вы заставляете компилятор учитывать, что эти числа читаются по-разному, что соответствует IEEE754 способ для парных. А потом 45,49,57,52 означает нечто совершенно иное, используя эту кодировку чисел.
Затем, учитывая, что символы равны 8 битам и двойным 32 битам, после приведения ваша память отображается следующим образом:
00101101001100010011100100110110,
00110100001101110011001100110100,
00101110001101010011010000110100
Затем, выполнив «ручную» интерпретацию IEEE754, вы получите три числа:
1.0073988518377597E-11
1.7061830703823944E-7
4.120100094429091E-11
Что странно не соответствует ни одному из ваших значений, так что ваши объемы памяти могут отличаться, или какое-то волшебство происходит во время приведений.
Хороший способ — не переосмыслить память, а преобразовать значение, а хорошее решение — использовать strtod()
от С или stod
из стандартной библиотеки C ++. Вы найдете много способов справиться с конверсией в других ответах или в постах, дублирующих этот.
Если вы хотите повеселиться с этим просто попробуйте плавает на этой веб-странице.
Вы должны использовать std::stod
функция (C ++ 11) с более современным компилятором
double result = std::stod(ss);
или, альтернативно, используйте std::stringstream
от <sstream>
std::stringstream sstrm(ss);
double d;
sstrm >> d;
Если вы используете приведение, то вы обрабатываете данные указателя как двойное значение, и это неправильно, так как указатель представляет собой целое число, представляющее адрес в памяти. Вам нужно интерпретировать данные, на которые указывает char*
чтобы получить правильный результат, используйте sscanf
, atof
или другие функции, которые принимают char*
и дать double
https://msdn.microsoft.com/en-us/library/aa272023%28v=vs.60%29.aspx
использование atof(const char*)
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
double pi;
const char * str = "3.14";
pi = atof(str);
cout << pi << endl;
return 0;
}
Ваш reinterpret_cast
подход вряд ли будет работать, если только переменная с плавающей запятой со значением -1964734.544
был буквально представлен в памяти с помощью набора символов {'-', '1', '9', '6', '4', '7', '3', '4', '.', '5', '4', '4'}
,
Таким образом, никакое значение с плавающей точкой не представляется в памяти. Период.
Если вы хотите решения C, используйте такие функции, как sscanf()
, strtod()
, и другие. Это возможно в C ++ из-за обратной совместимости, но большинство из них формально не рекомендуется.
Решение C ++ предполагает использование istringstream
, например;
#include <sstream>
#include <iostream>
int main()
{
std::istringstream s("-1964734.544");
double x;
if (s >> x)
std::cout << " x = " << x << '\n';
else
std::cout << "Whoops! String cannot be interpreted as floating point\n";
return 0;
}