我正在编写一个代码,将浮点数转换为它的等效字符串。例如,如果数字是:2.3456,那么字符串也应该是2.3456(没有尾随零)。
我在这两个链接上搜索了stackoverflow:
C++ convert floating point number to string
Convert Double/Float to string
但这些都略微偏离主题,因为他们倾向于要求以1eX格式或xE + 0格式表示。
这是我的尝试:
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
vector<char> V;
string S;
int i=0;
float f=3.14156;
float x=f*1e6;
long long int y=(long long int)(x);
while(y)
{
V.push_back(y%10+'0');
y/=10;
}
reverse(V.begin(),V.end());
for(i=0;i<V.size()-6;i++)
{
S.push_back(V[i]);
}
S.push_back('.');
for(;i<V.size();i++)
S.push_back(V[i]);
i=S.size();
while(i--)
{
if(S[i]=='0')
S.erase(S.begin()+i);
else break;
}
cout<<S<<"\n";
//system("pause");
return 0;
}
指向ideone的链接:http://ideone.com/Z8wBD7
我想知道如何有效地利用IEEE 754浮点表示标准(使用字符串指针或任何其他方法)并实现这样的转换,而无需使用任何预定义的库函数/扫描文件。
答案 0 :(得分:0)
#include<sstream>
#include<string>
#include<iostream>
using namespace std;
int main()
{
float val = 2.3456;
std::stringstream sstr;
sstr<<val;
string val_str;
sstr >> val_str;
cout << val_str;
}
答案 1 :(得分:0)
这是我的解决方案。为方便起见,我使用 <string>
,但没有使用其他库。 to_string(float x)
/ to_string(double x)
函数以 -1.23456789E-12
格式全精度以字符串形式返回数字。
to_string(float x, const uint decimals)
/ to_string(double x, const uint decimals)
函数以字符串形式返回具有指定小数位数的数字:例如,-12345.68
带有 2 个小数。这会降低精度,但对于控制台输出更方便。这里的数字仅限于 1.844E19
的量级。
在两种方法中都正确处理了舍入。
#define to_string to_string_old // use own to_string methods
#include <string>
#undef to_string // use own to_string methods
using namespace std;
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef int64_t slong;
typedef uint64_t ulong;
#define max_ulong 18446744073709551615ull
float pow(const float x, const uint n) {
float r = 1.0f;
for(uint i=0; i<n; i++) {
r *= x;
}
return r;
}
double pow(const double x, const uint n) {
double r = 1.0;
for(uint i=0; i<n; i++) {
r *= x;
}
return r;
}
void split_float(float x, uint& integral, uint& decimal, int& exponent) {
if(x>=10.0f) { // convert to base 10
if(x>=1E32f) { x *= 1E-32f; exponent += 32; }
if(x>=1E16f) { x *= 1E-16f; exponent += 16; }
if(x>= 1E8f) { x *= 1E-8f; exponent += 8; }
if(x>= 1E4f) { x *= 1E-4f; exponent += 4; }
if(x>= 1E2f) { x *= 1E-2f; exponent += 2; }
if(x>= 1E1f) { x *= 1E-1f; exponent += 1; }
}
if(x>0.0f && x<=1.0f) {
if(x<1E-31f) { x *= 1E32f; exponent -= 32; }
if(x<1E-15f) { x *= 1E16f; exponent -= 16; }
if(x< 1E-7f) { x *= 1E8f; exponent -= 8; }
if(x< 1E-3f) { x *= 1E4f; exponent -= 4; }
if(x< 1E-1f) { x *= 1E2f; exponent -= 2; }
if(x< 1E0f) { x *= 1E1f; exponent -= 1; }
}
integral = (uint)x;
float remainder = (x-integral)*1E8f; // 8 decimal digits
decimal = (uint)remainder;
if(remainder-(float)decimal>=0.5f) { // correct rounding of last decimal digit
decimal++;
if(decimal>=100000000u) { // decimal overflow
decimal = 0;
integral++;
if(integral>=10u) { // decimal overflow causes integral overflow
integral = 1;
exponent++;
}
}
}
}
void split_double(double x, uint& integral, ulong& decimal, int& exponent) {
if(x>=10.0) { // convert to base 10
if(x>=1E256) { x *= 1E-256; exponent += 256; }
if(x>=1E128) { x *= 1E-128; exponent += 128; }
if(x>= 1E64) { x *= 1E-64; exponent += 64; }
if(x>= 1E32) { x *= 1E-32; exponent += 32; }
if(x>= 1E16) { x *= 1E-16; exponent += 16; }
if(x>= 1E8) { x *= 1E-8; exponent += 8; }
if(x>= 1E4) { x *= 1E-4; exponent += 4; }
if(x>= 1E2) { x *= 1E-2; exponent += 2; }
if(x>= 1E1) { x *= 1E-1; exponent += 1; }
}
if(x>0.0 && x<=1.0) {
if(x<1E-255) { x *= 1E256; exponent -= 256; }
if(x<1E-127) { x *= 1E128; exponent -= 128; }
if(x< 1E-63) { x *= 1E64; exponent -= 64; }
if(x< 1E-31) { x *= 1E32; exponent -= 32; }
if(x< 1E-15) { x *= 1E16; exponent -= 16; }
if(x< 1E-7) { x *= 1E8; exponent -= 8; }
if(x< 1E-3) { x *= 1E4; exponent -= 4; }
if(x< 1E-1) { x *= 1E2; exponent -= 2; }
if(x< 1E0) { x *= 1E1; exponent -= 1; }
}
integral = (uint)x;
double remainder = (x-integral)*1E16; // 16 decimal digits
decimal = (ulong)remainder;
if(remainder-(double)decimal>=0.5) { // correct rounding of last decimal digit
decimal++;
if(decimal>=10000000000000000ull) { // decimal overflow
decimal = 0;
integral++;
if(integral>=10u) { // decimal overflow causes integral overflow
integral = 1;
exponent++;
}
}
}
}
string decimal_to_string_float(uint x, int digits) {
string r = "";
while((digits--)>0) {
r = (char)(x%10+48)+r;
x /= 10;
}
return r;
}
string decimal_to_string_double(ulong x, int digits) {
string r = "";
while((digits--)>0) {
r = (char)(x%10+48)+r;
x /= 10;
}
return r;
}
string to_string(const string& s){
return s;
}
string to_string(const char& c) {
return string(1, c);
}
string to_string(ulong x) {
string r = "";
do {
r = (char)(x%10+48)+r;
x /= 10;
} while(x);
return r;
}
string to_string(slong x) {
return x>=0 ? to_string((ulong)x) : "-"+to_string((ulong)(-x));
}
string to_string(uint x) {
string r = "";
do {
r = (char)(x%10+48)+r;
x /= 10;
} while(x);
return r;
}
string to_string(int x) {
return x>=0 ? to_string((uint)x) : "-"+to_string((uint)(-x));
}
string to_string(float x) { // convert float to string with full precision (<string> to_string() prints only 6 decimals)
string s = "";
if(x<0.0f) { s += "-"; x = -x; }
if(isnan(x)) return s+"NaN";
if(isinf(x)) return s+"Inf";
uint integral, decimal;
int exponent = 0;
split_float(x, integral, decimal, exponent);
return s+to_string(integral)+"."+decimal_to_string_float(decimal, 8)+(exponent!=0?"E"+to_string(exponent):"");
}
string to_string(double x) { // convert double to string with full precision (<string> to_string() prints only 6 decimals)
string s = "";
if(x<0.0) { s += "-"; x = -x; }
if(isnan(x)) return s+"NaN";
if(isinf(x)) return s+"Inf";
uint integral;
ulong decimal;
int exponent = 0;
split_double(x, integral, decimal, exponent);
return s+to_string(integral)+"."+decimal_to_string_double(decimal, 16)+(exponent!=0?"E"+to_string(exponent):"");
}
string to_string(float x, const uint decimals) { // convert float to string with specified number of decimals
string s = "";
if(x<0.0f) { s += "-"; x = -x; }
if(isnan(x)) return s+"NaN";
if(isinf(x)||x>(float)max_ulong) return s+"Inf";
const float power = pow(10.0f, min(decimals, 8u));
x += 0.5f/power; // rounding
const ulong integral = (ulong)x;
const uint decimal = (uint)((x-(float)integral)*power);
return s+to_string(integral)+(decimals==0 ? "" : "."+decimal_to_string_float(decimal, min((int)decimals, 8)));
}
string to_string(double x, const uint decimals) { // convert float to string with specified number of decimals
string s = "";
if(x<0.0) { s += "-"; x = -x; }
if(isnan(x)) return s+"NaN";
if(isinf(x)||x>(double)max_ulong) return s+"Inf";
const double power = pow(10.0, min(decimals, 16u));
x += 0.5/power; // rounding
const ulong integral = (ulong)x;
const ulong decimal = (ulong)((x-(double)integral)*power);
return s+to_string(integral)+(decimals==0 ? "" : "."+decimal_to_string_double(decimal, min((int)decimals, 16)));
}