简体   繁体   English

如何将char *转换为double?

[英]How to convert char* to double?

I've tried two methods to convert my char* type ss to a double type. 我尝试了两种方法将char*类型的ss转换为double类型。 Here is my code(Compiled in VC++6.0 windows64-bit ) 这是我的代码(在VC ++ 6.0 windows64-bit中编译)

int main()
{
    char *ss = "-1964734.544";
    cout<<ss<<endl;
    cout<<*reinterpret_cast<double*>(ss)<<endl;
    cout<<*(double *)ss<<endl;
}

The results are: 结果是:

-1964734.544
3.06123e-057
3.06123e-057

I'm not clear what is wrong and how to convert a char* to double. 我不清楚什么是错以及如何将char*转换为double。

You can use strtod like this: double smth=strtod(ss,NULL,10); 您可以像这样使用strtoddouble smth=strtod(ss,NULL,10);

It's possible to use a bit different syntax. 可以使用一些不同的语法。 See this for an example. 是一个例子。

your issue here is that A CAST IS NOT A CONVERSION : 您在这里的问题是, 投放不是转化

char *ss = "-1964734.544";
cout<<ss<<endl;
cout<<*reinterpret_cast<double*>(ss)<<endl;
cout<<*(double *)ss<<endl;

is that you're converting a string of characters into a number. 就是您要将一个字符串转换成数字。 What that means is that your memory is containing numbers being ascii values: 这意味着您的内存中包含作为ascii值的数字:

"-1964734.544"

is stored in memory as: 在内存中的存储方式为:

45, 49, 57, 54, 52, 55, 51, 52, 46, 53, 52, 52

which is in binary becomes: 二进制文件变为:

00101101,00110001,00111001,00110110,00110100,00110111,00110011,00110100,00101110,00110101,00110100,00110100

within the memory. 在内存中。 When converting to double, you're forcing the compiler to consider those numbers being read differently, which is following the IEEE754 way for doubles . 当转换为double时,您将强制编译器考虑以不同的方式读取这些数字,这遵循IEEE754的double方式 And then 45,49,57,52 means something totally different using that encoding of numbers. 然后45,49,57,52表示使用数字编码完全不同的东西。

Then, considering chars are 8bits and double 32bits, after a cast your memory is then mapped the following way: 然后,考虑字符是8位和32位双精度,在强制转换之后,您的内存将按以下方式映射:

00101101001100010011100100110110,
00110100001101110011001100110100,
00101110001101010011010000110100

Then doing a "manual" interpretation to IEEE754 you get three floats: 然后对IEEE754进行“手动”解释,您将得到三个浮点数:

1.0073988518377597E-11
1.7061830703823944E-7
4.120100094429091E-11

Which oddly is matching none of your values, so your memory sizes could be different, or some magic is happening during the casts. 奇怪的是,这两个值都不匹配您的值,因此您的内存大小可能会有所不同,或者在强制转换过程中发生了一些魔术。

The good way is to not reinterpret the memory, but to convert the value, and a good solution is to use strtod() from C, or stod from the standard library of C++. 好的方法是不重新解释内存,而是转换值,一个好的解决方案是使用C中的strtod()或C ++标准库中的stod You'll find many ways to handle the conversion in the other answers or from the posts that duplicates this one. 在其他答案中或从重复此答案的帖子中,您会找到许多方法来处理转换。

If you want to have more fun with that just try floats on that webpage . 如果您想从中获得更多乐趣,请尝试在该网页上浮动

You should use std::stod function (C++11) with a more modern compiler 您应该将std::stod函数(C ++ 11)与更现代的编译器一起使用

double result = std::stod(ss);

or, alternatively, use a std::stringstream from <sstream> 或者,也可以使用<sstream>std::stringstream

std::stringstream sstrm(ss);
double d;
sstrm >> d;

如果您使用强制转换,则将指针数据视为双精度值,这是错误的,因为指针是代表内存中地址的整数,您需要解释char*指向的数据以获得正确的结果,请使用sscanfatof或其他带char*double函数

https://msdn.microsoft.com/en-us/library/aa272023%28v=vs.60%29.aspx https://msdn.microsoft.com/en-us/library/aa272023%28v=vs.60%29.aspx

Use atof(const char*) 使用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;
}

Your reinterpret_cast approach would be unlikely to work unless a floating point variable with value of -1964734.544 was literally represented in memory using the set of characters {'-', '1', '9', '6', '4', '7', '3', '4', '.', '5', '4', '4'} . 除非使用一组字符{'-', '1', '9', '6', '4', '7', '3', '4', '.', '5', '4', '4'}来在内存中逐字表示值-1964734.544的浮点变量,否则您的reinterpret_cast方法不太可能起作用{'-', '1', '9', '6', '4', '7', '3', '4', '.', '5', '4', '4'}

No floating point value is represented in memory that way. 这样,内存中就不会表示浮点值。 Period. 期。

If you want C solutions, use functions like sscanf() , strtod() , and others. 如果需要C解决方案,请使用sscanf()strtod()等函数。 These are possible in C++ because of backward compatibility, but most of them are formally deprecated. 由于向后兼容,这些在C ++中是可能的,但是大多数都已正式弃用。

A C++ solution would involve using a istringstream , for example; 例如,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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM