下面的代码有什么问题?它在不使用sprintf或ostream的情况下将double转换为string
What is wrong with the following code? It converts double to string without using sprintf or ostream
我编写了下面的代码将double转换为string。我不应该使用sprint或ostream。输出很不稳定。
对应输出的输入列表:
- 2.0 - 2.0 2.5 - 2.5 -2.0 - -2.0
- 2.987 2.9879947598364142621957397469375 -2.987 - -2.9879947598364142621957397469375
#include <iostream>
#include <math.h>
using namespace std;
string reverse(string input);
string myDtoA(double num);
string itoa(int num);
int main()
{
double inp=-2.987;
cout<<myDtoA(inp)<<endl;
}
string myDtoA(double num)
{
if(num>0)
{
int inPart;
double intPart,fractPart;
fractPart = modf(num,&intPart);
inPart=(int)intPart;
string ret;
ret = itoa(inPart);
if(fractPart!=0)
{
ret.append(".");
double ceilOfFraction = ceil(fractPart);
while(ceilOfFraction !=0)
{
double inP,fP;
fractPart*=10;
fP=modf(fractPart,&inP);
int a =(int)inP;
ret.append(itoa(a));
fractPart=fP;
ceilOfFraction = ceil(fractPart);
}
}
else
{ret.append(".0");}
return ret;
}
else if(num==0)
{
return "0";
}
else if(num<0)
{
string ret = "-";
ret.append(myDtoA(-num));
return ret;
}
}
string itoa(int num)
{
char* str = new char[120];
int i=0;
// Process individual digits
while (num != 0)
{
int rem = num % 10;
str[i++] = (rem > 9)? (rem-10) + 'a' : rem + '0';
num = num/10;
}
string ret(str);
return reverse(ret);
}
/* A utility function to reverse a string */
string reverse(string input)
{
return std::string(input.rbegin(), input.rend());
}
浮点输出很难舍入。
这是我找到的关于这个主题的最新论文:
http://www.cs.tufts.edu/~ nr/cs257/归档/florian-loitsch/printf.pdf
在脚注中,你会发现一个参考:
[Steele Jr. and White(2004)] G. L. Steele Jr., J. L. White。如何准确地打印浮点数(回顾性)。20年来ACM SIGPLAN编程语言设计会议《实现1979-1999》,选集,第372-374页。ACM, 2004年。国际标准图书编号1-58113-623-4。doi: 10.1145/989393.989431 .
是一个精彩的阐述。没有人能够从你的程序中挑选出来,告诉你该怎么做。
问题在于您的itoa
的实现。如果itoa
的输入为0会发生什么?
输入为-2.987,输出-2.9879947598364142621957397469375应该是-2.9870000000000000994759830064140260219573974609375。注意,我的结果中没有零。那些缺失的零是由于itoa
中的错误。
一旦您达到处理单个十进制数字的地步,您的itoa
就完全是多余的。最好使用一个数组,将整数0到9映射到字符'0'到'9'。(或者你可以利用"0"到"9"在你的电脑上几乎肯定是连续字符的事实。情况并非总是如此,但我可以保证你不会和这样的野兽一起工作。
更好的是认识到以99475983…开头的子字符串是完全无关的。最好将其打印为-2.9870000000000001,甚至更好地打印为-2.987。
- 在没有太多条件句的情况下,我如何避免被零除
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 在未初始化映射的情况下,将值插入到映射的映射中
- 是默认情况下分配给char数组常量的值
- 为什么我不能在不创建字符串变量的情况下使用函数的字符串输出
- 如何在不产生任何垃圾的情况下获得C中的像素
- 在已经使用Git的情况下减少编译时间
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- 如何在没有信号的情况下从C++执行QML插槽
- 如何在不知道向量大小的情况下输入向量内部的向量?
- 为什么在某些情况下不写入此文件?
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 在没有Xcode的情况下在Mac捆绑包中嵌入框架
- UE4-如何在给定4个屏幕坐标的情况下缩放纹理或材质
- 为什么需要复制构造函数,在哪些情况下它们非常有用
- 如何在没有这个运算符的情况下实现默认运算符<<(ostream&,T)的类型?
- 在不复制的情况下从Ostream中获取char*
- 在什么情况下 ostream::write 或 ostream::operator<< 会失败?
- 如何在不格式化的情况下写入std::ostream
- 下面的代码有什么问题?它在不使用sprintf或ostream的情况下将double转换为string