首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >下面的代码有什么问题?它不使用sprintf或ostream将double转换为string。

下面的代码有什么问题?它不使用sprintf或ostream将double转换为string。
EN

Stack Overflow用户
提问于 2014-03-20 19:35:49
回答 2查看 162关注 0票数 2

我编写了以下代码,用于将double转换为string.I,我不应该使用sprintf或ostream。产出很不稳定。

具有相应输出的输入列表:

  • 2.0 2.0
  • 2.5 2.5
  • -2.0 -2.0
  • 2.987 2.9879947598364142621957397469375
  • -2.987 -2.9879947598364142621957397469375

代码语言:javascript
复制
 Where did these extra digits come from and how to overcome this?My code can be found below.

代码语言:javascript
复制
#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());
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-20 20:03:26

问题在于itoa的实现。如果itoa 的输入为0,会发生什么情况?

输入为-2.987的输出为-2.9879947478364142621957397469375为-2.9870000000000000994759830064140260219573974609375.。注意,我的结果中的零从您的结果中丢失了。那些丢失的零是因为itoa中的那个错误。

一旦达到处理单数小数位的程度,您的itoa就完全过火了。最好使用一个数组,将整数0到9映射到字符“0”到“9”。(或者你可以仅仅利用'0‘到'9’几乎可以肯定是计算机上的连续字符这一事实。这种情况一直没有发生过,但我可以很好地保证,你不会和这样的野兽一起工作。)

更好的方法是识别以99475983…开头的子字符串是完全无关的。最好打印为-2.9870000000000001,更好的打印为-2.987。

票数 1
EN

Stack Overflow用户

发布于 2014-03-20 19:39:07

四舍五入的浮点输出很难。

这是我最近在这个问题上发现的一篇论文:

http://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf

在脚注中,你会发现以下内容:

小斯蒂尔和White(2004) G.L. Steele Jr.还有J·L·怀特。如何准确打印fl燕点号(回溯)。1979年至1999年ACM SIGPLAN编程语言设计和实施会议20年,A SIGPLAN,第372至374页。ACM,2004年。ISBN 1-58113-623-4doi: 10.1145/989393.989431。

这是一次精彩的展览。没有人能够挑选你的程序,并告诉你如何处理它。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22543349

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档