日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

高精度加法(C语言实现)

發布時間:2023/11/16 windows 66 coder
生活随笔 收集整理的這篇文章主要介紹了 高精度加法(C语言实现) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

高精度加法(C語言實現)

介紹

眾所周知,整數在C和C++中以intlonglong long三種不同大小的數據存儲,數據大小最大可達2^64,但是在實際使用中,我們仍不可避免的會遇到爆long long的超大數運算,這個時候,就需要我們使用高精度算法,來實現巨大數的運算。

高精度的本質是將數字以字符串的形式讀入,然后將每一位分別存放入int數組中,通過模擬每一位的運算過程,來實現最終的運算效果。

今天,我們先講解高精度加法的C語言實現:


聲明

但其實我這版C語言的高精度算法封裝是很有問題的,沒有stl,字符串的操作是比較繁瑣的,以后熟悉C++后我會再寫一版簡易的,標準的高精度算法解析,但通過本文了解高精度的思路也是沒有問題的。


代碼實現

#include<stdio.h>
const int N = 100001;

int add(int a[], int b[], int c[], int len1, int len2)
{
    int t = 0, i = 0, max = len1 > len2 ? len1 : len2;
    //max指兩加數中較大者的位數,兩數之和c位數至少是max
    //標識變量t值為0或1,代表是否進位,初始為0
    for (; i <= max; i++)//運算到較大者位數后一位停止
    {
        c[i] = (a[i] + b[i] +t) % 10;//c的每一位為兩數該位之和加上t再模去10
        t = (a[i] + b[i] + t) / 10;//若和>10,則c[i]取其個位,t取其十位
    }//i遍歷至max+1
    if (c[i - 1] == 1)  return i;//若最高位為1,則返回c長度為max+1,即i
    else  return i - 1;//否則返回max,即i-1
}

int main()
{
    char str1[N], str2[N];//兩個數的字符串形式
    int a[N] = { 0 }, b[N] = { 0 }, c[N] = { 0 };//ab為加數,c為和
    char x;
    int len1 = 0, len2 = 0;//兩數位數
    do {
        scanf("%c", &x);
        str1[len1++] = x;
    }while (x != '\n');
    do{
        scanf("%c", &x);
        str2[len2++] = x;
    } while (x != '\n');
    len1--; len2--;//將數據讀入str1和str2,同時記錄位數
    for (int i = len1 - 1; i >= 0; i--)
        a[i] = str1[len1 - i - 1]-'0';
    for (int i = len2 - 1; i >= 0; i--)
        b[i] = str2[len2 - i - 1] - '0';//將ab的每一位轉換為整形存入數組
    int len3 = add(a, b, c, len1, len2);//執行高精度加法函數
    for (int i = len3 - 1; i >= 0; i--)
        printf("%d", c[i]);//輸出
    return 0;
}

思路分析

對大數來說,輸入便已經是一個有些麻煩的問題,無法讀取整形,只能以字符串形式,而且連有幾位數字都不知道。

    char str1[N], str2[N];//兩個數的字符串形式
    int a[N] = { 0 }, b[N] = { 0 }, c[N] = { 0 };//ab為加數,c為和
    char x;
    int len1 = 0, len2 = 0;//兩數位數
    do {
        scanf("%c", &x);
        str1[len1++] = x;
    }while (x != '\n');
    do{
        scanf("%c", &x);
        str2[len2++] = x;
    } while (x != '\n');
    len1--; len2--;//將數據讀入str1和str2,同時記錄位數

這里是主函數的變量聲明和輸入部分,若是程序只運行一次高精度運算,我們可以把變量的聲明放在主函數以外,來能減少函數的參數個數。

我們將讀取的字符賦值給x,然后再放入字符串數組,最后對x進行判斷,若x為換行符、空格或其他標識著數據輸入結束的字符,則終止循環。

同時,循環中變化的數組下標我們直接記為len1len2,代表兩個數字的長度。


顯然,字符形式的數字并不好運算,所以,我們需要將每一位轉換為整形存入數組,方便后續的計算。

那此時我們就會遇到一個問題,數組的第0位應該存放最高位還是存放個位呢?先看代碼實現:

    for (int i = len1 - 1; i >= 0; i--)
        a[i] = str1[len1 - i - 1]-'0';
    for (int i = len2 - 1; i >= 0; i--)
        b[i] = str2[len2 - i - 1] - '0';//將ab的每一位轉換為整形存入數組

在這段函數中,我們從高位向低位,將每一位的字符-'0',得到他的整形,然后存入數組,最終得到從低位到高位的新數組。

為什么要反過來存放呢,這就要考慮到一個最高位進位的問題。

數組后面存放最高位,在最高位進位時顯然比最高位放在第0位操作起來更方便,前者只需要在下一位+1,而后者想要進位,可能只能依靠于額外的標記變量了。

這種問題在后面的高精度乘法中更是明顯,所以,在高精度運算中,為了使高位靈活變動,我們一般都采用倒序的存放順序,即數組前面存低位,后面存高位。


到這里,我們就將準備工作做完了,數字已經放入數組,長度也已得知,這時我們就需要寫一個函數來運行高精度加法,代碼如下:

int add(int a[], int b[], int c[], int len1, int len2)
{
    int t = 0, i = 0, max = len1 > len2 ? len1 : len2;
    //max指兩加數中較大者的位數,兩數之和c位數至少是max
    //標識變量t值為0或1,代表是否進位,初始為0
    for (; i <= max; i++)//運算到較大者位數后一位停止
    {
        c[i] = (a[i] + b[i] +t) % 10;//c的每一位為兩數該位之和加上t再模去10
        t = (a[i] + b[i] + t) / 10;//若和>10,則c[i]取其個位,t取其十位
    }//i遍歷至max+1
    if (c[i - 1] == 1)  return i;//若最高位為1,則返回c長度為max+1,即i
    else  return i - 1;//否則返回max,即i-1
}

雖然圖中解析已經非常到位了,但我還是簡單講解一下吧。

首先從i=0位開始,將a[i]b[i]t相加,其個位便是c在該位的值,所以我們對他模上10,其大于10時需要進位,那我們就將其除以10,整形除法下取整,得到10,作為t的值,來參與下一位的運算。

最后,我們通過對最高位的01判斷,來決定返回max還是max+1


這時,我們已經將結果存入c了,只差輸出了,但想要輸出我們怎么知道c有幾位呢?最高位到底有沒有進位呢?那其實我們的函數返回值就是c的長度了。

    int len3 = add(a, b, c, len1, len2);//執行高精度加法函數
    for (int i = len3 - 1; i >= 0; i--)
        printf("%d", c[i]);//輸出

這樣,我們從后往前一位位輸出,就得出了最終結果了。


總結

總而言之言而總之,高精度算法就是單獨將每一位數字存入數組,分別計算,模擬我們手動計算的過程,接下來的減法和乘法除法的核心思想都是這個,那么以上便是對高精度加法算法的介紹,本文由涼茶coltea撰寫,思路來自AcWing,大佬yxc的課程。

總結

以上是生活随笔為你收集整理的高精度加法(C语言实现)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。