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

C#中double类型增量计算出现精度异常问题求助

浮点数精度异常的原因与解决方法

问题描述

需求逻辑:每次将数值增量0.1,累计到0.5时进位为整数后继续增量,但运行代码后出现0.30000000000000004、2.3000000000000003这类不符合预期的小数。

原代码

double value1 = 1.0;
double minorvalue = 0.1;
int count = 0;
double output = 0;
for (int i = 0; i < 1000; i++)
{
    double _over;
    if (count < 5)
    {
        
        _over = output + minorvalue;
        
        output = _over;
        Console.WriteLine(output);
        count++;
    }
    else
    {
        _over = (output + value1) - 0.5;
        

        output = _over;

        Console.WriteLine(output);
        minorvalue = 0.1;
        count = 0;
    }
}

Console.ReadLine();

异常输出示例

0.1
0.2
0.30000000000000004
0.4
0.5
1
1.1
1.2000000000000002
1.3000000000000003
1.4000000000000004
1.5000000000000004
2.0000000000000004
...

精度异常的原因

  • 二进制浮点数的本质限制:double类型属于二进制浮点数,它用二进制来表示小数。但十进制的0.1无法被二进制精确表示,只能存储一个近似值(类似十进制里无法精确表示1/3)。
  • 误差累积:每次对output累加这个近似的0.1,误差会不断累积,最终导致输出出现超出预期的长小数。

解决方法

方法1:使用decimal类型替代double

decimal是十进制浮点数,专门为精确的小数计算设计,适合处理精度要求高的小数场景。修改后的代码如下:

decimal value1 = 1.0m;
decimal minorvalue = 0.1m;
int count = 0;
decimal output = 0;
for (int i = 0; i < 1000; i++)
{
    decimal _over;
    if (count < 5)
    {
        _over = output + minorvalue;
        output = _over;
        Console.WriteLine(output);
        count++;
    }
    else
    {
        _over = (output + value1) - 0.5m;
        output = _over;
        Console.WriteLine(output);
        minorvalue = 0.1m;
        count = 0;
    }
}

Console.ReadLine();

方法2:用整数计数转换为目标值

避免直接操作小数,用整数记录累加的次数,最后再计算成对应的小数:

int count = 0;
int totalTicks = 0; // 每1个tick代表0.1
for (int i = 0; i < 1000; i++)
{
    if (count < 5)
    {
        totalTicks++;
        double output = totalTicks * 0.1;
        // 格式化输出保证显示正确
        Console.WriteLine(output.ToString("F1"));
        count++;
    }
    else
    {
        // 进位整数,等价于减去5个tick(0.5)再加10个tick(1.0)
        totalTicks = totalTicks - 5 + 10;
        double output = totalTicks * 0.1;
        Console.WriteLine(output.ToString("F1"));
        count = 0;
    }
}

Console.ReadLine();

方法3:格式化输出结果

如果只是显示问题,不需要精确计算,可以在输出时格式化字符串,指定小数位数:

// 在原代码的Console.WriteLine处修改为:
Console.WriteLine(output.ToString("F1"));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 15:33:15