Implement various hexadecimal conversions and hexadecimal conversions by yourself

Source: Internet
Author: User

Implement various hexadecimal conversions and hexadecimal conversions by yourself

In this article, we have implemented the conversion between hexadecimal numbers 2, 8, 10, and 16. In practice, APIs are rarely used or directly used.

If you are interested, you can write it yourself as an exercise.

OK. Go to the topic directly. Let's first talk about the algorithm for conversion between different hexadecimal formats (Baidu is also OK ).

 

Algorithm:

I,The decimal number is usually used, starting with it. To convert a decimal number to another decimal number, you can use the Division remainder method ]. Simply put, the number is always divided by the hexadecimal number (for example, the binary number is divided by 2), and then the remainder is obtained until the result is 0. The result is obtained from bottom to top.

For example, if 5 (decimal) is converted to binary, and the remainder of the result is 1, 0, and 1, the result is 101 (Binary ). 8 and 16 hexadecimal are the same process. Note that for hexadecimal notation, 10-15 is A-E.

II,Convert a non-decimal number to a decimal number. The bitwise multiplication is used (the name is out of order, just to be opposite to Division ). Simply put, the formula is: I * base ^ (J-1), I: number on the j-bit, base: hexadecimal j: j-bit. For example: 101 (decimal), after the formula is used: 1*2 ^ 2 + 0*2 ^ 1 + 1*2 ^ 0 = 5 (decimal ).

III,Other hexadecimal conversions. Since there is a "man in the middle" of the 10-in-the-middle mechanism, other conversions can only be done through this man in the middle. In fact, the conversion process is also very simple. For example, 8-to-2 conversion is "one divided into three"; 16-to-2 conversion is "one divided into four "; the opposite process is "three in one" and "four in one ".

Note that the above calculation process is for the integer part. If it is for the decimal part, the calculation will be different.

Now let's take a look at the decimal part calculation.

For the first, the decimal part is calculated as follows: the decimal part * base takes the integer, the decimal part continues * base, and then obtains the integer... until the decimal part is 0. For example, if the number of decimal digits is 0.5, convert it to an octal value:

0.5*8 = 4.0; that is, 4.

The decimal part is calculated as follows: I * base ^ (-j ). For example, if the decimal number is 0.11, the decimal part is calculated as follows: 1*2 ^ (-1) + 1*2 ^ (-2 ).

So, the above is the basic conversion process, the text is certainly not so clear, interested friends can Baidu, pictures and texts, better understanding.

 

Implementation:

Let's take a look at how to implement the function provided by. net. It's very simple. There are two lines of code, as shown below:

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

However, a disadvantage of Convert conversion is that it cannot calculate decimal points and negative numbers. It is tested in. net3.5. I don't know if it can be a higher version.

The following is my own implementation process (the core part is the conversion with the 10 hexadecimal system), as follows:

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> /// check the parameter /// </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 ("Incorrect base number specified by from! "); If (! (To = 10 | to = 2 | to = 8 | to = 16) throw new ArgumentException ("the base number specified by to is incorrect! "); String pattern = string. Empty; Regex regex = null; if (from = 2) pattern = @" ^ (\-| \ + ?) [01] + (. {0, 1} [01] + )? $ "; Else if (from = 8) pattern = @" ^ (\-| \ + ?) [01234567] + (. {01234567} [] + )? $ "; Else if (from = 10) pattern = @" ^ (\-| \ + ?) [0123456789] + (. {0123456789} [] + )? $ "; Else pattern = @" ^ (\-| \ + ?) [0123456789 | abcdef | ABCDEF] + (. {0123456789} [| abcdef | ABCDEF] + )? $ "; Regex = new Regex (pattern); if (! Regex. isMatch (value) throw new ArgumentException ("Source string does not match" + from. toString () + "hexadecimal specification ");} /// <summary> /// split string /// </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. toUppe R () {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. toSt Ring () ;}/// <summary> // convert other hexadecimal values to a decimal value (bitwise multiplication) /// </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 = 1 6; 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> // convert the 10 hexadecimal notation to another hexadecimal notation (tossing and Division) /// </summary> /// <param name = "values"> </param> /// <param name = "to"> </param> /// <returns> </returns> private static string TenToOthers (string [] values, int to) {int inte GerCurrent = 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 (decimaler Dec! = 0) {decimalerCurrent = decimalerDec * to; // split the double string to get the strArr = decimalerCurrent integer and decimal part. 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 (); // The default value is 32 bits. You can add a parameter to specify if (decimalerResult. length> 32) break;} return integerResult + ". "+ decimalerResult ;}/// <summary> /// convert other hexadecimal values. You can use the decimal value as the median /// </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, );}}

By the way, [Program Design], I personally think the most important thing is the word "design. Before writing code, we need to clarify the logic and think about the implementation process. After the design, the code will be written faster, the bug will be less, and the test will be easier. Therefore, when encountering a problem or requirement, remember not to knock on the Code immediately.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.