国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

自己實現(xiàn)各種進(jìn)制相互轉(zhuǎn)換

2019-11-14 14:04:23
字體:
供稿:網(wǎng)友

本文自己實現(xiàn)了2、8、10、16進(jìn)制數(shù)的相互轉(zhuǎn)換。實際中很少用到或者直接用api,所以大神老鳥請繞行。

有興趣的朋友也可以自己先寫寫,當(dāng)做練習(xí),僅此而已。

ok, 直接進(jìn)入主題。先說一下各進(jìn)制轉(zhuǎn)換的算法(百度一下也ok的)。

 

算法:

一、10 進(jìn)制數(shù)是平時所用到的,先從它開始。10進(jìn)制轉(zhuǎn)換為其它進(jìn)制的數(shù),用到的是【輾轉(zhuǎn)相除取余法】。簡單的說,就是該數(shù)一直除以進(jìn)制數(shù)(例如2進(jìn)制就除以2),然后取余數(shù),一直到結(jié)果為0。依次由下往上取余數(shù)就是結(jié)果。

例如:5(10進(jìn)制),轉(zhuǎn)換為2進(jìn)制,進(jìn)行上述過程,得到的余數(shù)分別是:1、0、1, 那么結(jié)果就是:101(二進(jìn)制)。對于 8和16進(jìn)制,也是同樣的過程。需要注意的是,對于16進(jìn)制,10-15 分別表示為:A-E。

二、非10進(jìn)制轉(zhuǎn)換為10進(jìn)制數(shù)。用到的是【位乘法】(名稱是亂起的,只是為了與除法相對)。簡單的說,公式就是:i * base^(j-1),i: 第j位上的數(shù), base:進(jìn)制  j: 第j位。例如:101(2進(jìn)制),運(yùn)用公式后就是:1 * 2^2 + 0 * 2^1 + 1 * 2^0 = 5(十進(jìn)制)。

三、其它進(jìn)制的相互轉(zhuǎn)換。既然有了10進(jìn)制這個“中間人”,其它的轉(zhuǎn)換只要通過這個中間人就可以了。實際上轉(zhuǎn)換的過程也很簡單,例如8進(jìn)制轉(zhuǎn)2進(jìn)制,就是“一分為三”;16進(jìn)制轉(zhuǎn)2進(jìn)制,就是“一分為四”;相反的過程就是“三位合一”、“四位合一”。

需要注意的是:上述計算過程都是針對整數(shù)部分,如果是小數(shù)部分,計算就不一樣了。

現(xiàn)在我們來看看小數(shù)部分的計算。

對于一、小數(shù)部分的計算是:小數(shù)部分 * base 取整數(shù),小數(shù)部分再繼續(xù) * base,再得到整數(shù)... 一直到小數(shù)部分為0。例如10進(jìn)制數(shù):0.5,轉(zhuǎn)為8進(jìn)制是:

0.5 * 8 = 4.0 ; 也就是:4。

對于二、小數(shù)部分的計算是:i * base^(-j)。 例如2進(jìn)制數(shù),0.11,小數(shù)部分的計算是:1 * 2^(-1) + 1 * 2^(-2)。

 so,上面就是基本的轉(zhuǎn)換過程,文字表達(dá)起來肯定沒那么清晰,有興趣的朋友可以百度,圖文并茂,更好理解。

 

實現(xiàn):

我們先來看一下利用.net提供的功能是如何實現(xiàn)的,很簡單,就2行代碼,如下:

static string SystemConvertUseAPI(string value, int from, int to){    int temp = Convert.ToInt32(value, from);    return Convert.ToString(temp, to);}

不過Convert自帶的轉(zhuǎn)換有一個缺點,就是無法計算小數(shù)和負(fù)數(shù),.net3.5 下測試的,不知道高版本的可不可以。

下面是我自己的實現(xiàn)過程,(核心部分就是與10進(jìn)制的相互轉(zhuǎn)換),如下:

    public static class SystemConvert    {        public static string ConvertValue(string value, int from, int to)        {            EnsureArguments(value, from, to);            char c = value[0];            string[] values = GetValues(value);            string result = string.Empty;            if (from == 10)                result = TenToOthers(values, to);            else if (to == 10)                result = OthersToTen(values, from);            else                result = OthersToOthers(values, from, to);            return c == '-' ? c.ToString() + result : result;        }        /// <summary>        /// 檢查參數(shù)        /// </summary>        /// <param name="value"></param>        /// <param name="from"></param>        /// <param name="to"></param>        PRivate static void EnsureArguments(string value, int from, int to)        {            if (value == null || value.Trim() == string.Empty)                throw new ArgumentNullException("value");            if (!(from == 10 || from == 2 || from == 8 || from == 16))                throw new ArgumentException("from 指定的基數(shù)不正確!");            if (!(to == 10 || to == 2 || to == 8 || to == 16))                throw new ArgumentException("to 指定的基數(shù)不正確!");            string pattern = string.Empty;            Regex regex = null;            if (from == 2)                pattern = @"^(/-|/+?)[01]+(.{0,1}[01]+)?$";            else if (from == 8)                pattern = @"^(/-|/+?)[01234567]+(.{0,1}[01234567]+)?$";            else if (from == 10)                pattern = @"^(/-|/+?)[0123456789]+(.{0,1}[0123456789]+)?$";            else                pattern = @"^(/-|/+?)[0123456789|abcdef|ABCDEF]+(.{0,1}[0123456789|abcdef|ABCDEF]+)?$";            regex = new Regex(pattern);            if (!regex.IsMatch(value))                throw new ArgumentException("源字符串不符合" + from.ToString() + "進(jìn)制規(guī)范");        }        /// <summary>        /// 拆分字符串        /// </summary>        /// <param name="value"></param>        /// <returns></returns>        private static string[] GetValues(string value)        {            value = value.Trim(new char[] { '+', '-', '0', '.' });            return value.Split(new char[] { '.' });        }        private static int Format16Char2Number(string c)        {            switch (c.ToUpper())            {                case "A":                    return 10;                case "B":                    return 11;                case "C":                    return 12;                case "D":                    return 13;                case "E":                    return 14;                case "F":                    return 15;                default:                    return Convert.ToInt32(c);            }        }        private static string Format16Number2Char(int number)        {            switch (number)            {                case 10:                    return "A";                case 11:                    return "B";                case 12:                    return "C";                case 13:                    return "D";                case 14:                    return "E";                case 15:                    return "F";                default:                    return number.ToString();            }        }        /// <summary>        /// 其它進(jìn)制轉(zhuǎn)換為10進(jìn)制(位乘法)        /// </summary>        /// <param name="value"></param>        /// <param name="from"></param>        /// <returns></returns>        private static string OthersToTen(string[] values, int from)        {            string result = string.Empty;            string integer = values[0];            string temp = string.Empty;            int integerCurrent = 0;            int integerResult = 0;            int index = integer.Length - 1;            bool is16 = from == 16;            foreach (var c in integer)            {                temp = c.ToString();                integerCurrent = is16 ? Format16Char2Number(temp) : Convert.ToInt32(temp);                integerResult += integerCurrent * (int)Math.Pow((double)from, (double)index);                index--;            }            if (values.Length <= 1)            {                return integerResult.ToString();            }            else            {                string decimaler = values[1];                double decimalerCurrent = 0.0;                double decimalerResult = 0.0;                index = -1;                foreach (var c in decimaler)                {                    temp = c.ToString();                    decimalerCurrent = is16 ? Format16Char2Number(temp) : Convert.ToDouble(temp);                    decimalerResult += decimalerCurrent * Math.Pow((from), (double)index);                    index--;                }                return (integerResult + decimalerResult).ToString();            }        }        /// <summary>        /// 10進(jìn)制轉(zhuǎn)換為其它進(jìn)制(輾轉(zhuǎn)相除法)        /// </summary>        /// <param name="values"></param>        /// <param name="to"></param>        /// <returns></returns>        private static string TenToOthers(string[] values, int to)        {            int integerCurrent = Convert.ToInt32(values[0]);            int remainder = 1;            bool is16 = to == 16;            string integerResult = string.Empty;            while (integerCurrent > 0)            {                remainder = integerCurrent % to;                integerResult = (is16 ? Format16Number2Char(remainder) : remainder.ToString()) + integerResult;                integerCurrent = integerCurrent / to;            }            if (values.Length <= 1)            {                return integerResult;            }            else            {                double decimalerCurrent = Convert.ToInt32(values[1]) / Math.Pow(10.0, (double)values[1].Length);                int decimalerInt = 0;                double decimalerDec = decimalerCurrent;                string decimalerResult = string.Empty;                string[] strArr;                while (decimalerDec != 0)                {                    decimalerCurrent = decimalerDec * to;                    //拆分double,得到整數(shù)和小數(shù)部分                    strArr = decimalerCurrent.ToString().Split(new char[] { '.' });                    decimalerInt = Convert.ToInt32(strArr[0]);                    if (strArr.Length > 1)                        decimalerDec = Convert.ToDouble(strArr[1]) / (Math.Pow(10.0, (double)strArr[1].Length));                    else                        decimalerDec = 0;                    decimalerResult += is16 ? Format16Number2Char(decimalerInt) : decimalerInt.ToString();                    //這里默認(rèn)精確到32位,可以加個參數(shù)指定                    if (decimalerResult.Length > 32)                        break;                }                return integerResult + "." + decimalerResult;            }        }        /// <summary>        /// 其它進(jìn)制互轉(zhuǎn)。以10進(jìn)制為中間值即可        /// </summary>        /// <param name="values"></param>        /// <param name="from"></param>        /// <param name="to"></param>        /// <returns></returns>        private static string OthersToOthers(string[] values, int from, int to)        {            string to10 = OthersToTen(values, from);            values = to10.Split(new char[] { '.' });            return TenToOthers(values, to);        }    }

順帶一句,【程序設(shè)計】,個人覺得最重要的是“設(shè)計”二字。在寫代碼前,我們需要理清邏輯,想好實現(xiàn)的過程;當(dāng)設(shè)計好了,代碼寫起來會更快、bug 也會更少,測試起來也更容易。所以,碰到一個問題或需求,切記不要馬上就敲代碼。


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 佛山市| 平昌县| 平南县| 长寿区| 化州市| 东乌| 汶川县| 沾益县| 精河县| 宝丰县| 合作市| 岳阳市| 仁寿县| 左云县| 保德县| 德庆县| 沈丘县| 安远县| 台北县| 肃宁县| 从江县| 石首市| 巴彦县| 旺苍县| 霍林郭勒市| 澎湖县| 武川县| 镇平县| 郧西县| 吴旗县| 南和县| 南开区| 海兴县| 达日县| 治县。| 黑龙江省| 长沙县| 井研县| 南川市| 宝兴县| 林口县|