c#动态保留小数位数的数值格式化方法实例----从小数点后非零数字保留两位进行四舍五入

c#动态保留小数位数的数值格式化方法实例----从小数点后非零数字保留两位进行四舍五入

1、功能介绍

1. 输入的数字是整数,则直接返回整数部分的字符串表示。

2. 如果输入的数字是小数,则执行以下步骤:

2.1 如果小数部分.后以".0"开头(例如:0.00013),需要动态计算显示,不允许固定保留小数位数。这意味着不能直接保留两位小数,因为无法确定后面有多少位0。直接保留会显示为0或者0.00

2.2 如果小数部分不以".0"开头,直接进行四舍五入并保留小数位数。

该方法的目的是根据输入的数字进行判断和处理,使得最终输出的字符串满足上述保留小数的规则。

2、代码案例

csharp 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp4
{
    class Program
    {
        static void Main(string[] args)
        {

            Console.WriteLine($"原始值:567--------转换后的值:{FormatNumber(567)}");
            Console.WriteLine($"原始值:0.00000196--------转换后的值:{FormatNumber(0.00000196)}");
            Console.WriteLine($"原始值:831.00002455--------转换后的值:{FormatNumber(831.00002455)}");
            Console.WriteLine($"原始值:76.008921--------转换后的值:{FormatNumber(76.008921)}");
            Console.WriteLine($"原始值:0.003333333--------转换后的值:{FormatNumber(0.003333333)}");
            Console.WriteLine($"原始值:0.54241218115613401401552902563902978171--------转换后的值:{FormatNumber(0.54241218115613401401552902563902978171)}");

        }


        /// <summary>
        /// 计算保留小数
        /// 1、整数:如果是整数则直接返回
        /// 2、小数:
        ///     2.1小数点后以.0开头,需要动态计算显示,假如0.00013,直接保留两位岂不是0.00了,又不确定后面有多少位0,不允许固定保留小数位
        ///     2.2小数点后不为.0开头,直接四舍五入保存
        /// 0.00001显示为0.00001
        /// 0.00000196显示为0.000002
        /// 76.008921显示为76.0089
        /// 831.00002455显示为831.000025
        /// 0.003333333显示为0.0033
        /// 0.54241218115613401401552902563902978171显示为0.54
        /// 567显示为567
        /// </summary>
        /// <param name="number"></param>
        /// <returns></returns>
        static string FormatNumber(double number)
        {
            try
            {
                // 判断是否整数,如果是,直接返回整数部分
                if (number == Math.Floor(number))
                {
                    return number.ToString("0");
                }
                else if (number < 0)
                {
                  //引用.NET(C#)将十进制数四舍五入保留第一个非零小数(Math.Round()),见6、其他方法地址
                    int precision = 0;
                    var val = number;
                    while (Math.Abs(val) < 1)
                    {
                        val *= 10;
                        precision++;
                        if (precision > 10) // 设置一个最大精度限制,避免无限循环
                            break;
                    }
                    return ((double)Math.Round(number, precision + 1)).ToString();
                }
                else
                {
                    // 获取小数部分
                    double decimalPart = number - Math.Floor(number);
                    // 转换小数部分为字符串
                    string decimalPartString = decimalPart.ToString("0.##############################");
                    // 找到小数点的位置
                    int dotIndex = decimalPartString.IndexOf('.');

                    // 计算小数部分的 ".0" 开头的零的数量
                    int zeroCount = 0;
                    for (int i = dotIndex + 1; i < decimalPartString.Length; i++)
                    {
                        if (decimalPartString[i] == '0')
                        {
                            zeroCount++;
                        }
                        else
                        {
                            break;
                        }
                    }

                    // 生成保留小数位数的格式字符串
                    string formatString;
                    if (zeroCount == 0)
                    {
                        formatString = "0.00"; // 如果没有 ".0" 开头的零,保留两位小数
                    }
                    else
                    {
                        formatString = "0." + new string('#', 2 + zeroCount); // 否则,根据零的数量生成格式字符串
                    }

                    return number.ToString(formatString);
                }
            }
            catch (Exception ex)
            {
                return number.ToString("0.##");
            }
        }


    }
}

3、输出结果

4、封装扩展方法

csharp 复制代码
public static class FormatExtension
{
    public static string FormatNumber(this double number)
    {
        try
        {
            // 判断是否整数,如果是,直接返回整数部分
            if (number == Math.Floor(number))
            {
                return number.ToString("0");
            }
            else
            {
                // 获取小数部分
                double decimalPart = number - Math.Floor(number);
                // 转换小数部分为字符串
                string decimalPartString = decimalPart.ToString("0.##############################");
                // 找到小数点的位置
                int dotIndex = decimalPartString.IndexOf('.');

                // 计算小数部分的 ".0" 开头的零的数量
                int zeroCount = 0;
                for (int i = dotIndex + 1; i < decimalPartString.Length; i++)
                {
                    if (decimalPartString[i] == '0')
                    {
                        zeroCount++;
                    }
                    else
                    {
                        break;
                    }
                }

                // 生成保留小数位数的格式字符串
                string formatString;
                if (zeroCount == 0)
                {
                    formatString = "0.00"; // 如果没有 ".0" 开头的零,保留两位小数
                }
                else
                {
                    formatString = "0." + new string('#', 2 + zeroCount); // 否则,根据零的数量生成格式字符串
                }

                return number.ToString(formatString);
            }
        }
        catch (Exception ex)
        {
            return number.ToString("0.##");
        }
    }

}

5、控制台调用

csharp 复制代码
     double num = 2567.11233;
     Console.WriteLine(num.FormatNumber());

6、其他方法地址

.NET(C#)将十进制数四舍五入保留第一个非零小数(Math.Round())

如果有哪位前辈或同胞了解类似以上转换合适的方法、以及依赖包,可以说明下,一起学习进步,本次遇到记录一下~

相关推荐
前端 贾公子2 小时前
v-if 与 v-for 的优先级对比
开发语言·前端·javascript
嗯嗯=3 小时前
python学习篇
开发语言·python·学习
不会c嘎嘎5 小时前
QT中的常用控件 (二)
开发语言·qt
是一个Bug5 小时前
50道核心JVM面试题
java·开发语言·面试
烛阴6 小时前
C# 正则表达式(5):前瞻/后顾(Lookaround)——零宽断言做“条件校验”和“精确提取”
前端·正则表达式·c#
她和夏天一样热6 小时前
【观后感】Java线程池实现原理及其在美团业务中的实践
java·开发语言·jvm
lkbhua莱克瓦246 小时前
进阶-索引3-性能分析
开发语言·数据库·笔记·mysql·索引·性能分析
郑州光合科技余经理6 小时前
技术架构:上门服务APP海外版源码部署
java·大数据·开发语言·前端·架构·uni-app·php
篱笆院的狗6 小时前
Java 中的 DelayQueue 和 ScheduledThreadPool 有什么区别?
java·开发语言
2501_941809146 小时前
面向多活架构与数据地域隔离的互联网系统设计思考与多语言工程实现实践分享记录
java·开发语言·python