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

C语言如何正确将小数四舍五入保留两位小数 解决货币找零精度问题

货币找零程序问题修复方案

问题根源

问题是二进制浮点数的固有精度限制导致的:float 类型无法精确表示 0.01、0.2 这类十进制小数,输入的99.99实际存储时会是略小于99.99的数值(例如99.98999786),运算过程中误差持续累计,最后就会出现差0.01无法正确识别的问题,单独调用取整函数也无法解决底层的精度误差。

推荐修复方案:统一转换为整数(单位:分)运算

完全规避浮点数误差的最优方案是把所有金额换算为以「分」为单位的整数进行计算,同时保留你原有的指针用法,修改后代码如下:

#include <stdio.h>
#include <math.h>
#define COINS_TYPES 14
// 新增:元转分的换算系数
#define YUAN_TO_FEN 100

void read_num(int* cash_fen);
void analyze_and_result(int* arr, int* arr_val_fen, int* cash_fen);

int main(){
    int cash_fen;
    int coins[COINS_TYPES] = { 0 };
    // 面值全部转为分单位的整数
    int coins_val_fen[COINS_TYPES] = { 20000,10000,5000,2000,1000,500,200,100,50,20,10,5,2,1 };

    for (;;) {
        read_num(&cash_fen);
        analyze_and_result(coins, coins_val_fen, &cash_fen);
        break;
    }
    return 0;
}

void read_num(int* cash_fen) {
    float cash;
    printf("Type amount of cash to exchange for coins\n");
    scanf("%f", &cash);
    // 转成分单位整数,加1e-6避免浮点数取整误差
    *cash_fen = (int)(cash * YUAN_TO_FEN + 1e-6);
}

void analyze_and_result(int* arr, int* arr_val_fen, int* cash_fen) {
    for (int i = 0;i < COINS_TYPES;i++) {
        int flag = *cash_fen / arr_val_fen[i];
        if (flag) {
            arr[i] = flag;
            *cash_fen -= arr_val_fen[i] * flag;
            // 输出时转换回元单位,格式和原来一致
            printf("Coins quantity %0.2f : %d\n", arr_val_fen[i] * 1.0 / YUAN_TO_FEN, arr[i]);
        }
    }
}

改动说明

  • 所有金额计算全部改用int类型以分为单位运算,从根源上消除浮点数精度误差
  • 保留了原有的指针传参逻辑,符合你学习指针的需求
  • 输入时先读取浮点金额再转成分整数,兼容用户的输入习惯
  • 输出时自动转回元单位,和原有输出格式完全一致

临时应急方案(不改动数据类型)

如果你暂时不想修改整体数据结构,可以在计算面值数量时补充极小的误差修正值抵消精度问题,仅需要修改analyze_and_result里的flag计算逻辑:

// 加1e-6抵消浮点数累计误差
int flag = (*cash + 1e-6) / arr_val[i];

该方案仅能临时解决问题,长期使用还是推荐整数运算的方案,可靠性更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 18:54:03