将int(实际上是十进制)转换为字符串(1234到" 123.4")

时间:2014-09-04 18:51:33

标签: c++

我有整数,例如1234,但实际上它意味着123.4,所以它是编码的十进制,我应该乘以10 ^ -1。

如何轻松地将此int转换为字符串“123.4”?我应该准确地说“123.4”,而不是“123.3999999”。所以我需要类似itoa但更高级的东西。

upd 字符串我的意思是char数组。

7 个答案:

答案 0 :(得分:3)

将数字转换为std::string

char buffer[12];
std::string s = itoa(1234, buffer, 10);

或者:

std::string s = std::to_string(intNum);

然后只需将insert()十进制字符输入其中:

s.insert(s.length()-1, "."); 

或者:

s.insert(s.length()-1, 1, '.'); 

答案 1 :(得分:2)

如果数字超过CPU的浮点精度,则除以10会导致精度损失。相反,使用这样的东西:

string intNumStr = itoa(intNum);
char lastDigit = intNumStr[intNumStr.length() - 1];
intNumStr[intNumStr.length() - 1] = '.';
intNumStr += string(lastDigit);

答案 2 :(得分:1)

我很好奇这些转换的相对性能,所以我用一些方法的天真版本做了一些测试。一些注意事项和注意事项:

  • 以下转换代码没有错误检查,并且未经过测试(即,不要复制/粘贴代码)。
  • 某些方法仅适用于正整数。
  • 方法没有等效输出。例如,数字0-9(' 0.0',' .0','。')和因子10(' 10' ,' 10。',' 10.0')。您应该确切地确定这些情况下您想要的输出。
  • 我首先选择最简单的算法,然后只在我需要的时候进行优化。你真的需要~1亿整数/秒的性能吗?
  • 不幸的是,我没有C ++ 11编译器来测试std::to_string()版本。

测试的算法是:

string toString1 (const int a)
{
    char buffer[32];
    string result = itoa(a, buffer, 10);
    char lastDigit = result[result.length() - 1];
    result[result.length() - 1] = '.';
    result += lastDigit;

    return result;
}

void toString1a (string& Output, const int a)
{
    char buffer[32];
    Output = itoa(a, buffer, 10);
    char lastDigit = Output[Output.length() - 1];
    Output[Output.length() - 1] = '.';
    Output += lastDigit;
}

string toString2 (const int a) {
    float f = a * 0.1f;
    ostringstream ss;
    ss << f;

    return ss.str();
}    

const char* toString3 (const int a)
{
    static char s_buffer[32]; //Careful!

    itoa(a, s_buffer, 10);
    size_t len = strlen(s_buffer);
    char lastDigit = s_buffer[len-1];
    s_buffer[len-1] = '.';
    s_buffer[len] = lastDigit;
    s_buffer[len+1] = '\0';

    return s_buffer;
}    

const char* toString4 (char* pBuffer, const int a)
{
    itoa(a, pBuffer, 10);
    size_t len = strlen(pBuffer);
    char lastDigit = pBuffer[len-1];
    pBuffer[len-1] = '.';
    pBuffer[len] = lastDigit;
    pBuffer[len+1] = '\0';

    return pBuffer;
}

void toString4a (char* pBuffer, const int a)
{
    itoa(a, pBuffer, 10);
    size_t len = strlen(pBuffer);
    char lastDigit = pBuffer[len-1];
    pBuffer[len-1] = '.';
    pBuffer[len] = lastDigit;
    pBuffer[len+1] = '\0';
}

const char* toString5 (char* pBuffer, const int a)
{
    snprintf(pBuffer, 16, "%.1f", a/10.0);
    return pBuffer;
}

const char* toString6 (char* pBuffer, const int a)
{
    snprintf(pBuffer, 16, "%d.%01d", a / 10, a % 10);
    return pBuffer;
}

string toString7 (const int a)
{
    ostringstream stream;
    stream << (a / 10) << '.' << (a % 10);
    return stream.str();
}

string toString8 (const int a)
{
    char buffer[16];
    string result = _itoa(a, buffer, 10);
    result.insert(result.length()-1, 1, '.'); 
    return result;
}

基于以上方法对1亿个整数(从0开始)运行基本基准测试。如果性能对您的案例非常重要,请为您自己的具体用例进行概述/基准测试。

  • toString1 = 0.64 sec(itoa to string)
  • toString1a = 0.61 sec(inplace,no return)
  • toString2 = 33.4秒(stringstream,哎哟!)
  • toString3 = 0.52秒(itoa,静态缓冲区)
  • toString4 = 0.52 sec(itoa)
  • toString4a = 0.52秒(itoa,inplace)
  • toString5 = 6.35秒(snprintf,float)
  • toString6 = 2.29秒(snprintf,两个整数)
  • toString7 = 33.3秒(stringstream,两个整数)
  • toString8 = 0.70秒(itoa和string :: insert)

哪一个更好&#34;真的取决于你需要什么。我个人会使用最简单的流案例(toString7),除非我绝对确定我需要其他方法的表现。

答案 3 :(得分:0)

#include <sstream>
#include <iostream>
#include <string>
using namespace std;

string toString(int a) {
    float f = a * 0.1f;
    ostringstream ss;
    ss << f;
    return ss.str();
}

int main() {
    cout << toString(101);
    return 0;
}

答案 4 :(得分:0)

对于c ++ 11,你可以使用它:

std::string toString( int i )
{
    int t = abs( i );
    return ( i < 0 ? "-", "" ) + std::to_string( t / 10 ) + "." + std::to_string( t % 10 );
}

对于pre c ++ 11,您可以将其替换为std::stringstreamsnprintf

std::string toString( int i )
{
    char buffer[128] = { '-' };
    int t = abs( i );
    snprintf( buffer + 1, sizeof(buffer) - 1, "%d.%d", t / 10, t % 10 );
    return std::string( i < 0 ? buffer : buffer + 1 );
}

答案 5 :(得分:0)

#include <sstream>
using namespace std;

string Decimal1ToString(int i)
{
    ostringstream stream;
    stream << (i / 10) << '.' << (i % 10);
    return stream.str();
}

注意使用整数/和%。 这可以防止精度损失。

答案 6 :(得分:0)

这是我的版本:

#include <iostream>

int main()
{
    char price[18];
    _itoa_s(98321, price, 10);
    int len = strlen(price);
    char lastDigit = price[len - 1];
    price[len - 1] = '.';
    price[len] = lastDigit;
    price[len + 1] = 0;

    printf(price);

    return 0;
}