我有整數,例如1234,但實際上它的意思是123.4,所以它是十進制編碼,我應該乘以10^-1。int(實際上是十進制)到字符串(1234到「123.4」)
我怎樣才能輕鬆地將此int轉換爲字符串「123.4」?我應該有「123.4」,而不是「123.3999999」。所以我需要類似itoa
但更先進。
upd by string我的意思是char數組。
我有整數,例如1234,但實際上它的意思是123.4,所以它是十進制編碼,我應該乘以10^-1。int(實際上是十進制)到字符串(1234到「123.4」)
我怎樣才能輕鬆地將此int轉換爲字符串「123.4」?我應該有「123.4」,而不是「123.3999999」。所以我需要類似itoa
但更先進。
upd by string我的意思是char數組。
我很好奇這些轉換的相對性能,所以我用幾個方法的天真版本做了一些測試。一些注意事項和注意事項:
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;
}
基本基準是在100個百萬個整數(從0開始)上述方法運行。如果性能對您的情況非常重要,請爲您的確切使用情況進行簡介/基準測試。
哪一個「更好」取決於你的需求。就我個人而言,我會使用最簡單的流案例(toString7),除非我確定我需要其他方法的性能。
怎麼樣使用'std :: string :: insert()'而不是? – 2014-09-04 23:49:06
使用'string :: insert'添加'toString8()'的情況,它比直接緩衝區操作case'toString1()'慢了一點。 – uesp 2014-09-05 12:32:32
很有意思,謝謝!在我的情況下,我關心性能因爲我使用這個在HFT – javapowered 2014-09-05 19:57:40
#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;
}
流是不可接受的慢 – javapowered 2014-09-04 19:04:36
@javapowered你測量了什麼嗎?你有號碼可以分享嗎? – 2014-09-04 19:57:19
不,但我90%確定使用'itoa'並插入'。'。在結果字符串將更快,無bug – javapowered 2014-09-04 20:00:33
如果數字超過CPU的浮點精度,則除以10會導致精度損失。相反,使用這樣的事情:
string intNumStr = itoa(intNum);
char lastDigit = intNumStr[intNumStr.length() - 1];
intNumStr[intNumStr.length() - 1] = '.';
intNumStr += string(lastDigit);
stringstream是無法接受的慢 – javapowered 2014-09-04 19:04:20
@javapowered'std :: stringstream'甚至沒有在這個答案中提到?!? – 2014-09-04 19:22:37
@πάνταῥεῖ這是第一次。 – 2014-09-04 19:24:47
對於C++ 11你可以使用這個:
std::string toString(int i)
{
int t = abs(i);
return (i < 0 ? "-", "") + std::to_string(t/10) + "." + std::to_string(t % 10);
}
預C++ 11你可以用std::stringstream
或snprintf
替換:
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);
}
#include <sstream>
using namespace std;
string Decimal1ToString(int i)
{
ostringstream stream;
stream << (i/10) << '.' << (i % 10);
return stream.str();
}
注意使用integer /和%。 這可以防止精確度損失。
轉換數量爲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, '.');
'itoa'寫入'char *'所以我不能調用'.length()',可能我應該調用'strlen'或類似的東西。也'插入'爲char *也沒有定義太 – javapowered 2014-09-05 07:21:31
再仔細看看我的例子。'itoa()'確實將'char *'返回到正在寫入的緩衝區,但是'char *'正被分配給'std :: string',它具有'length()'和'insert() '方法。 – 2014-09-05 15:06:22
這是我的版本:
#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;
}
爲正整數,'的std :: to_string(1234/10)+ 「」 + std :: to_string(1234%10)'。對於否定,請在絕對值上進行此操作,並在前面加上'「 - 」'。 – 2014-09-04 18:52:46
你嘗試了什麼,你被困在哪裏?如果我們一直要求代表1用戶,我沒有看到一個觀點,爲什麼你應該滿足這些最低限度的要求! – 2014-09-04 18:54:23
@ T.C。至少使用http://www.cplusplus.com/reference/cstdlib/div/代替1234到10兩次會更好嗎? – javapowered 2014-09-04 18:58:51