標籤:
在項目中,大家可能都遇到過,需要把十進位轉換為其他進位的情況,google上一搜,已經有很多2進位、8進位、16進位和十進位的轉換方法。但是在一些項目中,這些可能無法滿足要求,可能需要17、18甚至是32、36進位和十進位的轉換,那麼我們應該怎麼辦呢?不可能為每一種進位都去寫一個函數,那樣可不是明智之舉。所以我這裡提供一個十進位與N進位之間的互轉函數(N<=32)。
N進位函數1、準備工作
在寫N進位函數之前,需要有一個用於儲存表示N進位字元的基礎資料表,這裡我用一個表函數表示:
CREATE FUNCTION xavi.fn_NSystemTable()RETURNS @temp TABLE (id SMALLINT IDENTITY, [Char] CHAR(1),[Ascii] SMALLINT)ASBEGIN DECLARE @ignoreAscii TABLE ([Ascii] SMALLINT) DECLARE @i INT SET @i = 58 WHILE(@i <= 64) BEGIN INSERT INTO @ignoreAscii VALUES (@i) SET @i = @i + 1 END SET @i = 0 WHILE(@i < 43) BEGIN IF NOT EXISTS (SELECT 1 FROM @ignoreAscii WHERE [Ascii] = @i + 48) BEGIN INSERT INTO @temp VALUES (CHAR(@i + 48),@i + 48) END SET @i = @i + 1 END RETURNEND
2、十進位轉換為N進位
CREATE FUNCTION xavi.fn_DecimalToNSystem (@bigInt BIGINT, @n TINYINT)RETURNS VARCHAR(100)AS BEGIN Declare @result VARCHAR(100),@mode INT,@remainder INT, @iRet CHAR(1) SELECT @mode = @bigInt, @result = ‘‘ WHILE(1 = 1) BEGIN IF(@bigInt = 0 OR @n = 0 OR @n = 1) BEGIN SET @result = CONVERT(VARCHAR(100),@bigInt) BREAK END IF(@mode = 0) BEGIN BREAK END SET @remainder = @mode % @n SET @mode = @mode / @n SELECT @iRet = [Char] FROM xavi.fn_NSystemTable() ns WHERE ns.id = @remainder + 1 SET @result = @iRet + @result END RETURN @resultEND
3、N進位轉換為十進位
CREATE FUNCTION xavi.fn_NSystemToDecimal (@nSys VARCHAR(100), @n TINYINT)RETURNS BIGINTASBEGIN Declare @result int,@iPos int,@iTmp int Select @result = 0,@iPos = 0 While(@iPos < Len(@nSys)) BEGIN SELECT @iTmp = ns.id - 1 FROM xavi.fn_NSystemTable() ns WHERE ns.[Char] = SUBSTRING(@nSys,LEN(@nSys) - @iPos,1) Set @result = @result + @iTmp * POWER(CAST(@n AS BIGINT),cast(@iPos AS BIGINT)) Set @iPos = @iPos + 1 END RETURN @resultEND
注意:目前測試下來對於最高進位(36進位),最多支援13位,但是我想這也足夠了,因為36進位所能表示的範圍遠比10進位的13位元大得多,0<=y<=36 * 3612 + 36 * 3611 +......+ 36 * 361 + 36。所以一個N進位來說能表示的範圍應該為:0<=y<=N * Nx + N * Nx-1 +......+ N * N1 + N。
如何使用
那麼我們應該怎麼使用這些函數呢,這裡舉一個自增36進位欄位的表的例子。
首先建立一個表:
CREATE TABLE xavi.tb_Test( ID CHAR(10) PRIMARY KEY, Account VARCHAR(20), [Name] NVARCHAR(10))
然後建立一個觸發器:
CREATE TRIGGER xavi.tr_TestInsertON xavi.tb_TestINSTEAD OF INSERT ASSET NOCOUNT ONDECLARE @maxID BIGINT, @n TINYINT, @nSystemChar VARCHAR(10)SET @n = 36SELECT @maxID = ISNULL(MAX(xavi.fn_NSystemToDecimal(ID,@n)),0) FROM xavi.tb_TestSET @nSystemChar = xavi.fn_DecimalToNSystem(@maxID + 1, @n)INSERT INTO xavi.tb_Test(ID,Account,[Name])SELECT REPLICATE(‘0‘,10 - LEN(@nSystemChar)) + @nSystemChar, Account, [Name]FROM INSERTED
接著往這個表裡插入100條冊數資料:
DECLARE @i INTSET @i = 1WHILE(@i <= 100)BEGIN INSERT INTO xavi.tb_Test VALUES(@i,LEFT(REPLACE(CONVERT(VARCHAR(100),NEWID()),‘-‘,‘‘),10),LEFT(REPLACE(CONVERT(VARCHAR(100),NEWID()),‘-‘,‘‘),10)) SET @i = @i + 1END
執行看下錶裡的資料,可以得到如的結果:
從這個結果應該可以觀察到,ID這一列已經是36進位的表示形式了。
擴充用法
有了這個N進位函數,那麼我們再生產一些唯一編碼、訂單號等一些編碼時,就可以用更少的位元,表示更大的範圍
一 基礎--進位轉化
今天第一天正式上課學習的是基礎<進位轉化>,上面的圖表達的是各種進位之間的關係,同時也表達了學習IT的學習方法< 學習一個建模思想 形成處理事情條理化的條件反射>
今天起我這隻樹上的蝸牛將開始一點一點的將我經曆的內容全部點滴記錄下來。
1 學習目的
學習一個建模思想 形成處理事情條理化的條件反射。
2 主要內容
簡介 十進位有10個基數:0-9;二進位有兩個基數:0-1;八進位有八個基數:0-7;十六進位有16個基數:0-9;A(10)-F(15);
1)十進位A到其他進位B(A進位到B進位)
要點:就用A除以B,用短除法並取餘,直到商為0,由下到上餘數串連即為B;
2)二進位---十進位
步驟 1 寫底數 2寫指數(右到左從0開始)3乘係數 (右到左)4 累加
例 0,111(二進位) 7(十進位)
1)2 2 2 2
2)2³+2²+2 +2º
3)0*2³+1*2²+1*2 +1*2º
4)0+4+2+1=7
同理 其他進位A到十進位即可使用公式
3)其他進位轉化
1 *二進位到八進位
從右至左,三位元字一組利用421(二進位111到十進位即為4+2+1=7)進行轉化;
*二進位到十六進位
從右至左,四位元字一組利用8421(二進位1111到十進位即為8+4+2+1=15)進行轉化;
2 八進位到二進位/十六進位到二進位
遵循八進位/十六進位的每一位元字就用二進位代替即可;
來自網路大卡的深解
C#中二進位、八進位、十六進位和十進位之間的相互轉化問題
首先來簡單的看一下,C#本身內建的X進位之間的轉換功能如下:
//十進位轉二進位 Console.WriteLine(Convert.ToString(69, 2));
//十進位轉八進位 Console.WriteLine(Convert.ToString(69, 8));
//十進位轉十六進位 Console.WriteLine(Convert.ToString(69, 16));
//二進位轉十進位 Console.WriteLine(Convert.ToInt32(”100111101″, 2));
//八進位轉十進位 Console.WriteLine(Convert.ToInt32(”76″, 8));
//十六進位轉十進位 Console.WriteLine(Convert.ToInt32(”FF”, 16));
十六進位 轉向 十進位:
int myTempR = int.Parse("EA",System.Globalization.NumberStyles.HexNumber);
十進位 轉向 十六進位:
this.myResult.Text = myTempR.ToString("X");C#語言有很多值得學習的地方,這裡我們主要介紹C#實現轉換十六進位,包括介紹用來表示十六進位的枚舉值是 HexNumber等方面。
C#實現轉換十六進位
任何資料在電腦內部都是以二進位儲存的,所以進位與資料的儲存無關,只與輸入輸出有關。所以,對於進位轉換,我們只關心字串中的結果。
在上面的第 4 條中提到了 ToString() 方法可以將數值轉換成字串,不過在字串中,結果是以十進位顯示的。現在我們帶給它加一些參數,就可以讓C#實現轉換成十六進位——使用 ToString(string) 方法。
這裡需要一個 string 類型的參數,這就是格式說明符。十六進位的格式說明符是 "x" 或者 "X",使用這兩種格式說明符的區別主要在於 A-F 六個數字:"x" 代表 a-f 使用小寫字母表示,而 "X" 而表示 A-F 使用大字字母表示。如下例:
private void TestHex()
{
int a = 188;
this.textBox1.Text = "";
this.textBox1.AppendText("a(10) = " + a.ToString() + "\n");
this.textBox1.AppendText("a(16) = " + a.ToString("x") + "\n");
this.textBox1.AppendText("a(16) = " + a.ToString("X") + "\n");
}
運行結果如下:
a(10) = 188
a(16) = bc
a(16) = BC
這時候,我們可能有另一種需求,即為了顯示結果的整齊,我們需要控制十六進位表示的長度,如果長度不夠,用前置的 0 填補。解決這個問題,我們只需要在格式說明符“x”或者“X”後寫上表示長度的數字就行了。比如,要限制在 4 個字元的長度,可以寫成“X4”。在上例中追加一句:
this.textBox1.AppendText("a(16) = " + a.ToString("X4") + "\n");
其結果將輸出 a(16) = 00BC。
現在,我們還要說一說如何將一個表示十六進位數的字串轉換成整型。這一轉換,同樣需要藉助於 Parse() 方法。這裡,我需要 Parse(string,System.Globalization.NumberStyles) 方法。第一個參數是表示十六進位數的字串,如“AB”、“20”(表示十進位的 32) 等。第二個參數 System.Globalization.NumberStyles 是一個枚舉類型,用來表示十六進位的枚舉值是 HexNumber。因此,如果我們要將“AB”轉換成整型,就應該這樣寫:int b = int.Parse("AB", System.Globalization.NumberStyles.HexNumber),最後得到的 b 的值是 171。
SQL Server進位