C#夯实基础之浮点数理解,相互转换封装帮助类

背景:工作中遇到项目,封装成各种转换数据类型的帮助类,工具类,这里总结学习,方便日后之用

先看基础;八大整型数值类型,关于它们无需多言,可参考官网

https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/builtin-types/integral-numeric-types

其次浮点类型,这个和想的不一样,因为我理解是,好歹这个数到底有多大呢?

https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/builtin-types/floating-point-numeric-types

为何官方只是给出一个范围呢?是因为这个数是根据有效位数来的,比如一个超大的数5645456454545445445454564654,

或是0.00000000000000000000000000000045454

那么直接转为科学计数法,留相应的有效位数,比如double近似可理解为无限大,或是无限小

Console.WriteLine(1236545646546545645454544654654654546546546545644234.34d);
            Console.WriteLine(0.000000000000000000000000000000000000000000000000000000000000000000034d);
            Console.WriteLine(1236545646546545645454f);
            Console.WriteLine(0.000000000000000000000000000000000000000000000000000000000000000000034f);
/*
output:
1.23654564654655E+51
3.4E-68
1.236546E+21
0
5.64564432324324E+48
请按任意键继续. . .
*/

在编程中,数据转换用到地方非常多,如果用语言内置的转换,有转换麻烦,或是会抛出异常等等问题,

因此我们自己封装一种简单,安全比较健壮的方法,如下所示,使用测试代码见如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConvertDemo
{

    public abstract class DateUtil
    {
        public static readonly DateTime NullDate = DateTime.Parse("1900-01-01");

        public static string GetTimeBucket(DateTime? dt1, DateTime? dt2, string format)
        {
            var format1 = format;
            var format2 = format;

            if (dt1 == null || dt2 == null)
            {
                return dt1.ToFormatDateTime(format) + " - " + dt2.ToFormatDateTime(format);
            }

            if (dt1.Value.Year == dt2.Value.Year)
            {
                format2 = format2.Replace("yyyy-", "");
                format2 = format2.Replace("yyyy/", "");
                format2 = format2.Replace("yyyy年", "");
                format2 = format2.Replace("yyyy", "");

                if (dt1.Value.Month == dt2.Value.Month)
                {
                    format2 = format2.Replace("MM-", "");
                    format2 = format2.Replace("MM/", "");
                    format2 = format2.Replace("MM月", "");
                    format2 = format2.Replace("MM", "");

                    if (dt1.Value.Day == dt2.Value.Day)
                    {
                        format2 = format2.Replace("dd-", "");
                        format2 = format2.Replace("dd/", "");
                        format2 = format2.Replace("dd日", "");
                        format2 = format2.Replace("dd", "");
                    }
                }
            }

            var result = dt1.ToFormatDateTime(format1);

            if (!string.IsNullOrWhiteSpace(format2))
            {
                result += " - " + dt2.ToFormatDateTime(format2);
            }

            return result;
        }
    }
}

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConvertDemo
{
    public static class DateTimeExtension
    {
        //不支持:new DateTime("1970-1-1");
        private static DateTime NullDate = DateTime.Parse("1970-1-1");
        public static string ToFormatDateTime(this DateTime obj, string format)
        {
            if (obj == DateTime.MinValue || obj == NullDate)
            {
                return string.Empty;
            }
            return obj.ToString(format);
        }
        public static string ToFormatDateTime(this DateTime? obj, string format)
        {
            if (!obj.HasValue) return string.Empty;

            return obj.Value.ToFormatDateTime(format);
        }

        public static string GetWeek(this DateTime? obj)
        {
            if (obj != null)
            {
                DayOfWeek dw = obj.Value.DayOfWeek;
                switch (dw)
                {
                    case DayOfWeek.Monday:
                        return "周一";
                    case DayOfWeek.Tuesday:
                        return "周二";
                    case DayOfWeek.Wednesday:
                        return "周三";
                    case DayOfWeek.Thursday:
                        return "周四";
                    case DayOfWeek.Friday:
                        return "周五";
                    case DayOfWeek.Saturday:
                        return "周六";
                    case DayOfWeek.Sunday:
                        return "周日";
                }
            }
            return "";
        }

        public static bool IsNullOrMin(this DateTime? obj)
        {
            return !obj.HasValue || (obj.Value.IsNullOrMin());
        }

        public static bool IsNullOrMin(this DateTime obj)
        {
            return obj == DateTime.MinValue || obj == NullDate;
        }

        public static DateTime ValueOrDefault(this DateTime? obj)
        {
            return obj.HasValue ? obj.Value : NullDate;
        }

        public static DateTime ValueOrDefault(this DateTime obj)
        {
            return !IsNullOrMin(obj) ? obj : NullDate;
        }

        /// <summary>
        /// DateTime时间格式转换为13位带毫秒的Unix时间戳
        /// </summary>
        /// <param name="time"> DateTime时间格式</param>
        /// <returns>Unix时间戳格式</returns>
        public static long DateTimeToUnixLong(this DateTime time)
        {
            DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
            return (long)(time - startTime).TotalMilliseconds;
        }

        /// <summary>
        /// 13位带毫秒的Unix时间戳转为DateTime时间格式
        /// </summary>
        /// <param name="timeStamp">13位带毫秒的Unix时间戳</param>
        /// <returns>C#格式时间</returns>
        public static DateTime UnixLongToDateTime(this long timeStamp)
        {
            DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
            return dtStart.AddMilliseconds(timeStamp);
        }

        /// <summary>
        /// DateTime时间格式转换为10位不带毫秒的Unix时间戳
        /// </summary>
        /// <param name="time"> DateTime时间格式</param>
        /// <returns>Unix时间戳格式</returns>
        public static int DateTimeToUnixInt(this DateTime time)
        {
            DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
            return (int)(time - startTime).TotalSeconds;
        }
    }
}

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConvertDemo
{
    public static class ConverterSafe
    {
        #region 公用基础方法,转为double,decimal
        /// <summary>
        /// 转成double型,失败返回0
        /// </summary>
        /// <param name="item">待转换的对象</param>
        /// <param name="defaultVal">转换失败后的默认值</param>
        /// <returns>转换后的结果</returns>
        public static double ToDouble(object item, double defaultVal = 0)
        {
            if (item == null)
                return defaultVal;
            if ((item as Enum) != null)
                return Convert.ToInt64(item);
            string sItem = Convert.ToString(item);
            if (sItem.Trim().ToLower() == "true")
                return 1;
            if (sItem.Trim().ToLower() == "false")
                return 0;
            double result = 0;
            return double.TryParse(sItem, out result) ? result : defaultVal;
        }
        public static decimal ToDecimal(object item, decimal defaultVal = 0)
        {
            if (item == null)
                return defaultVal;
            if ((item as Enum) != null)
                return Convert.ToInt64(item);
            string sItem = Convert.ToString(item);
            if (sItem.Trim().ToLower() == "true")
                return 1;
            if (sItem.Trim().ToLower() == "false")
                return 0;
            decimal result = 0;
            return (item != null && decimal.TryParse(item.ToString(), out result)) ? result : 0m;
        }
        #endregion

        #region 转换为整数型sbyte和byte,short和ushort,int和uint,long和ulong,包括上下取整int
        public static sbyte ToSByte(object item, int defaultVal = 0)
        {
            double tmp = ToDouble(item, defaultVal);
            if (tmp > sbyte.MaxValue)
                return sbyte.MaxValue;
            if (tmp < sbyte.MinValue)
                return sbyte.MinValue;
            return Convert.ToSByte(tmp);
        }
        public static byte ToByte(object item, int defaultVal = 0)
        {
            double tmp = ToDouble(item, defaultVal);
            if (tmp <= 0)
                return 0;
            if (tmp > byte.MaxValue)
                return byte.MaxValue;
            return Convert.ToByte(tmp);
        }
        public static short ToInt16(object item, short defaultVal = 0)
        {
            double tmp = ToDouble(item, defaultVal);
            if (tmp > short.MaxValue)
                return short.MaxValue;
            return Convert.ToInt16(tmp);
        }
        public static ushort ToUInt16(object item, ushort defaultVal = 0)
        {
            double tmp = ToDouble(item, defaultVal);
            if (tmp <= 0)
                return 0;
            if (tmp > ushort.MaxValue)
                return ushort.MaxValue;
            if (tmp < ushort.MinValue)
                return ushort.MinValue;
            return Convert.ToUInt16(tmp);
        }
        public static int ToInt32(object item, int defaultVal = 0)
        {
            double tmp = ToDouble(item, defaultVal);
            if (tmp > int.MaxValue)
                return int.MaxValue;
            return Convert.ToInt32(tmp);
        }
        public static uint ToUInt32(object item, uint defaultVal = 0)
        {
            double tmp = ToDouble(item, defaultVal);
            if (tmp <= 0)
                return 0;
            if (tmp > uint.MaxValue)
                return uint.MaxValue;
            if (tmp < uint.MinValue)
                return uint.MinValue;
            return Convert.ToUInt32(tmp);
        }
        public static long ToInt64(object item, long defaultVal = 0)
        {
            double tmp = ToDouble(item, defaultVal);
            if (tmp > long.MaxValue)
                return long.MaxValue;
            return Convert.ToInt64(tmp);
        }
        public static ulong ToUInt64(object item, ulong defaultVal = 0)
        {
            double tmp = ToDouble(item, defaultVal);
            if (tmp <= 0)
                return 0;
            if (tmp > ulong.MaxValue)
                return ulong.MaxValue;
            if (tmp < ulong.MinValue)
                return ulong.MinValue;
            return Convert.ToUInt64(tmp);
        }

        public static int ToCeiling(object item)
        {
            double result = ToInt32(item);
            return Convert.ToInt32(Math.Ceiling(result));
        }
        public static int ToFloor(object item)
        {
            double result = ToInt32(item);
            return Convert.ToInt32(Math.Floor(result));
        }
        #endregion

        #region  转换为浮点数double,float,decimal
        /// <summary>
        /// 保留N位有效小数,转换失败返回0
        /// </summary>
        /// <param name="item">待转换的对象</param>
        /// <param name="n">保留小数位数</param>
        /// <returns>转换对象并舍位后的结果</returns>
        public static double ToDouble(object item, int n)
        {
            return ToDouble(ToDouble(item).ToString("f" + n));
        }

        /// <summary>
        /// 转成single型 不成功返回0
        /// </summary>
        /// <param name="item">待转换的对象</param>
        /// <returns>转换后的结果</returns>
        public static float ToSingle(object item)
        {
            double tmp = ToDouble(item);
            if (tmp > float.MaxValue)
            {
                return float.MaxValue;
            }
            return Convert.ToSingle(tmp);
        }
        /// <summary>
        /// 保留N位有效小数
        /// </summary>
        /// <param name="item">待转换的对象</param>
        /// <param name="n">保留小数位数</param>
        /// <returns>转换后的结果</returns>
        public static float ToSingle(object item, int n)
        {
            return ToSingle(ToSingle(item).ToString("f" + n));
        }

        #endregion

        #region 转为bool,guid,datetime,任意对象type
        public static bool ToBoolean(object item)
        {
            return Convert.ToBoolean(ToDouble(item));
        }
        public static string ToString(object item)
        {
            return Convert.ToString(item);
        }
        public static Guid ToGuid(object item)
        {
            Guid id = Guid.Empty;
            if (item == null)
                return id;
            if (item is Guid)
                id = (Guid)item;
            else
            {
                string s = item as string;
                if (!string.IsNullOrEmpty(s))
                    Guid.TryParse(s, out id);
                else
                {
                    byte[] btyItem = item as byte[];
                    if (btyItem != null)
                        id = new Guid(btyItem);
                }
            }
            return id;
        }
        public static DateTime ToDateTime(object item)
        {
            DateTime defaultDate = DateTime.Parse("1970-1-1");
            if (item == null)
                return defaultDate;
            DateTime.TryParse(item.ToString().Trim().TrimStart("Tt".ToArray()), out defaultDate);
            return defaultDate;
        }
        public static T ToType<T>(object item) {
            Type t = typeof(T);
            object result = null;
            if (t == typeof(sbyte))
                result = ToSByte(item);
            else if (t == typeof(byte))
                result = ToByte(item);
            else if (t == typeof(short))
                result = ToInt16(item);
            else if (t == typeof(int))
                result = ToInt32(item);
            else if (t == typeof(long))
                result = ToInt64(item);
            else if (t == typeof(Boolean))
                result = ToBoolean(item);
            else if (t == typeof(Guid))
                result = ToGuid(item);
            else if (t == typeof(DateTime))
                result = ToDateTime(item);
            else if (t == typeof(double))
                result = ToDouble(item);
            else if (t == typeof(float))
                result = ToSingle(item);
            else if (t == typeof(decimal))
                result = ToDecimal(item);
            //是Enum子类,通过具体数转为枚举值
            else if (typeof(Enum).IsAssignableFrom(t))
                result = Enum.ToObject(t,ToInt32(item));
            //碰巧item是当前需要类型的派生类
            else if (t.IsAssignableFrom(item.GetType()))
                result = item;
            else
                //是其他值类型比如结构类型,直接返回实例,否则返回引用null
                result = t.IsValueType ? Activator.CreateInstance(t) : null;
            return (T)item;
        }
        #endregion
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值