c#大數加法


在C#中,我們經常需要表示整數。但是,c#的基本數據類型中,最大的long也只能表示-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807之間的數。貨幣類型也不是無限大。如果我們需要表示更大的數,就需要用到一定的算法來完成。

這次,我和大家一起討論一下c#的大數運算之加法。

這次,我們只考慮正數的整數加法。

我們的代碼要封裝到一個結構里面。這個結構的結構先擺出來。

 public struct BigInt
        {
          
            public int[] num  ;
            public int length ;
          
           
         }        

我們的思路是讀取一個string表示的大數,然后通過算法來計算,返回一個string類型的結果。

為了便於計算,我們首先要把賦值過來的的string轉換為一個int數組。這個數組就是代碼里的num[]數組。

我們要把這個數的個位存到num[0]里,十位存到num[1]里,以此類推。於是我添加了一個構造函數。

  public BigInt(string theint):this()
            {
           
               
                this.num = new int[200];
                this.length = 0;
                this.length = theint.Length - 1;
                for (int i = 0; i <= theint.Length - 1; i++)
                {
                    this.num[i] = Convert.ToInt32(theint[theint.Length - 1 - i].ToString());
                
                }
            }

例如 調用BigInt(“123”) 時,num[0]=3,num[1]=2,num[2]=1 length=2 (為了方便,這里的length是指數組的坐標上限,不是數組元素的個數)

我們如果能直接把string賦給BigInt類型的變量該多方便啊,那么我們現在就來實現它。 怎么實現呢?其實把一種數據類型變量賦值給另一種時,都需要轉換,為什么有的可以直接賦值呢,是因為這里進行的是隱式轉換。所以我們就來編寫從string到BigInt的隱式轉換。代碼和構造函數類似。

 public static implicit operator BigInt(string theint)
            {
                BigInt b = new BigInt();
               
                b.num = new int[200];
                b.length = 0;
                b.length = theint.Length - 1;
                for (int i = 0; i <= theint.Length - 1; i++)
                {
                    b.num[i] = Convert.ToInt32(theint[theint.Length - 1 - i].ToString());
                
                }
                return b;
            }

implicit說明轉換方式是隱式轉換。operator是各種轉換和操作符的標志。

當然,較小的數也可以直接從int轉過來。所以再寫一個int=>BigInt的隱式轉換。

 public static implicit operator BigInt(long theint2)
            {
                string theint = theint2.ToString();
               
              
                return theint;
            }

 

准備工作做好了,現在開始計算過程。

在這里,我們通過模擬學生列豎式的方法來計算。首先要從最低位也就是個位加起,滿10要向高位進1,也就是數組的下一個元素的值加一。我們直接重寫+操作符,代碼見下

  public static BigInt operator +(BigInt b1, BigInt b2)
            {
                BigInt b3 = b1;//要返回的加法結果
                BigInt b4 = b2;
                int big = b3.length > b4.length ? b3.length : b4.length;//獲取兩個加數的最高位數,從0到最高位數依次加法
                

                for ( int i = 0; i <= big; i++) {
                    b3.num[i] += b4.num[i];//加法計算
                    b3.num[i + 1] += b3.num[i] / 10;//進位
                    b3.num[i] %= 10; //進位后剩下的
                } 
                //確定更新后的位數
                big=199;
                while (b3.num[big] == 0&&big!=0) {
                    big--;
                }
                b3.length = big;
                return b3;
            }

 

 public static BigInt operator +(BigInt b1, BigInt b2)這一句,BigInt是加法返回的結果的類型;operator +說明重寫的是加法,(BigInt b1, BigInt b2)是兩個加數。計算原理是豎式的加法計算。
代碼里我加入了注釋,應該可以看懂

最后,為了顯示BigInt類型的值,我們編寫一個由BigInt到string的隱式轉換。

public static implicit operator string(BigInt theint)
            {
                string b = "";
              
                for (int i = theint.length; i >=0 ; i--)
                {
                    b += theint.num[i].ToString();
                }
                return b;
            }

由於存入數組時時從低位到高位的,所以我們輸出string時要反轉回來。

至此,大數加法編寫完成。下面是代碼清單。

public struct BigInt
        {
          
            public int[] num  ;
            public int length ;
            #region 初始賦值
            
            public BigInt(string s):this()
            {
                this = s;
            }
            public static implicit operator BigInt(string theint)
            {
                BigInt b = new BigInt();
               
                b.num = new int[200];
                b.length = 0;
                b.length = theint.Length - 1;
                for (int i = 0; i <= theint.Length - 1; i++)
                {
                    b.num[i] = Convert.ToInt32(theint[theint.Length - 1 - i].ToString());
                
                }
                return b;
            }
            public static implicit operator BigInt(long theint2)
            {
                string theint = theint2.ToString();
               
              
                return theint;
            }
            #endregion
           
            public static implicit operator string(BigInt theint)
            {
                string b = "";
              
                for (int i = theint.length; i >=0 ; i--)
                {
                    b += theint.num[i].ToString();
                }
                return b;
            }

           
 public static BigInt operator +(BigInt b1, BigInt b2) { BigInt b3 = b1;//要返回的加法結果 BigInt b4 = b2; int big = b3.length > b4.length ? b3.length : b4.length;//獲取兩個加數的最高位數,從0到最高位數依次加法 for ( int i = 0; i <= big; i++) { b3.num[i] += b4.num[i];//加法計算 b3.num[i + 1] += b3.num[i] / 10;//進位 b3.num[i] %= 10; //進位后剩下的  } //確定更新后的位數 big=199; while (b3.num[big] == 0&&big!=0) { big--; } b3.length = big; return b3; }
} 

另外注,此貼純屬技術研究,如需大數運算,.net有專門的類型,無需自己寫代碼。至於類型是什么,你們自己去找吧。O(∩_∩)O~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM