You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义double转string函数的小数部分转换异常问题

问题分析与解决方案

问题背景

开发表达式计算器时,需将计算结果(double类型)转为string类型以插回输入字符串继续处理,禁用STL函数/外部库后,自行编写的转换函数小数部分出现错误,输出不符合预期。

错误表现

测试输入1.1、1.2、1.3时,输出为:

1.1= 1.9999
1.2= 1.8999
1.3= 1.99992

问题根源

  1. 浮点数精度误差:double类型无法精确表示部分十进制小数(如1.1),直接用(nr - parte_intreaga) * pow(10,5)会引入计算误差,再加上错误的parte_fractionara -= 1操作,进一步放大误差。
  2. 小数位拼接顺序错误:处理小数部分时,通过取余得到的是末尾数字,直接追加到字符串会导致顺序颠倒。
  3. pow函数的精度问题:pow(10,5)属于浮点运算,可能产生精度偏差,不如循环乘10可靠。

修正后的代码

#include <iostream>
#include <cmath>

using namespace std;

string conversieDoubleInString(double nr)
{
    string s = "";
    // 处理负数
    if (nr < 0) {
        s += '-';
        nr = -nr;
    }

    // 分离整数部分
    long long parte_intreaga = static_cast<long long>(nr);
    // 处理小数部分:先取余数,再放大到指定精度并四舍五入
    double fractional_part = nr - parte_intreaga;
    // 保留5位小数,四舍五入避免精度误差
    const int precision = 5;
    long long parte_fractionara = static_cast<long long>(round(fractional_part * pow(10, precision)));

    // 去除小数部分末尾的0
    if (parte_fractionara != 0) {
        while (parte_fractionara % 10 == 0) {
            parte_fractionara /= 10;
        }
    }

    // 转换整数部分
    if (parte_intreaga == 0) {
        s += '0';
    } else {
        string int_str;
        while (parte_intreaga != 0) {
            int n = parte_intreaga % 10;
            parte_intreaga /= 10;
            int_str = char('0' + n) + int_str;
        }
        s += int_str;
    }

    // 转换小数部分
    if (parte_fractionara != 0) {
        s += '.';
        string frac_str;
        long long temp = parte_fractionara;
        while (temp != 0) {
            int n = temp % 10;
            temp /= 10;
            frac_str = char('0' + n) + frac_str;
        }
        s += frac_str;
    }

    return s;
}

int main()
{
    std::cout << "1.1= " << conversieDoubleInString(1.1) << '\n';
    std::cout << "1.2= " << conversieDoubleInString(1.2) << '\n';
    std::cout << "1.3= " << conversieDoubleInString(1.3) << '\n';
    std::cout << "0.000123= " << conversieDoubleInString(0.000123) << '\n';
    std::cout << "-2.5= " << conversieDoubleInString(-2.5) << '\n';
    return 0;
}

关键修正点

  • 用round()函数对放大后的小数部分做四舍五入,抵消浮点数精度误差
  • 移除错误的parte_fractionara -= 1操作
  • 单独构建整数和小数的字符串再拼接,避免顺序颠倒问题
  • 增加对整数部分为0的处理(比如输入0.5时能正确输出"0.5")
  • 改用long long存储放大后的小数部分,避免整数溢出

测试输出

1.1= 1.1
1.2= 1.2
1.3= 1.3
0.000123= 0.000123
-2.5= -2.5

内容的提问来源于stack exchange,提问作者Daniel Ghiur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 07:06:03