最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C/C++整數(shù)乘積的溢出問題的解決

 更新時間:2024年02月11日 10:14:15   作者:劍心訣  
整數(shù)乘積的溢出問題是指兩個整數(shù)相乘得到的結(jié)果超過了所能表示的數(shù)據(jù)類型的范圍,本文給大家介紹了C/C++整數(shù)乘積的溢出問題的解決,需要的朋友可以參考下

一、為什么會溢出?

整數(shù)乘積的溢出問題是指兩個整數(shù)相乘得到的結(jié)果超過了所能表示的數(shù)據(jù)類型的范圍。

在計算機中,整數(shù)的表示是有限的,即存在一個最大值和最小值。當進行乘法運算時,如果結(jié)果超出了整數(shù)的表示范圍,就會發(fā)生溢出。這種情況下,計算結(jié)果將不再準確,并且可能導(dǎo)致數(shù)據(jù)丟失或錯誤的計算結(jié)果。

比如:int類型,C 語言標準規(guī)定了 int 類型必須至少能表示 -32767 到 32767 之間的整數(shù),也就是說,int 類型的最小值和最大值范圍為 -215 到 215-1。

一般而言,int 類型在 32 位操作系統(tǒng)上占用 4 個字節(jié)(32 位),在 64 位操作系統(tǒng)上占用 8 個字節(jié)(64 位)。使用 limits.h 頭文件可以查看當前編譯器中 int 類型的最大值和最小值。

#include<iostream>
#include <limits.h>
using namespace std;

int main()
{
    printf("INT_MIN: %d\n", INT_MIN);
    printf("INT_MAX: %d\n", INT_MAX);

    system("pause");
    return 0;
} 

至于INT_MIN的值為什么是-2147483648,原因是:

在 32 位系統(tǒng)中,int 類型通常占據(jù) 4 個字節(jié),即 32 位,而最小的帶符號整數(shù)(-2^31)的二進制補碼表示恰好對應(yīng)于 -2147483648。

二、怎樣解決?

可以使用更大范圍的整數(shù)類型,比如 long long 或者 int64_t 等,以支持更大范圍的數(shù)值計算。

根據(jù)取值范圍,靈活選用整數(shù)類型:

C數(shù)據(jù)類型最小值最大值
[signed] char-128127
unsigned char0255
short-3276832767
unsigned short065535
int-2 147 483 6482 147 483 647
unsigned04 294 967 295
long-2 147 483 6482 147 483 647
unsigned long04 294 967 295
int32_t-2 147 483 6482 147 483 647
uin32_t04 294 967 295
int64_t-9 223 372 036 854 775 8089 223 372 036 854 775 807
uint64_t018 446 744 073 709 551 615

32位程序上C語言整型數(shù)據(jù)類型的典型取值范圍

C數(shù)據(jù)類型最小值最大值
[signed] char-128127
unsigned char0255
short-3276832767
unsigned short065535
int-2 147 483 6482 147 483 647
unsigned04 294 967 295
long-9 223 372 036 854 775 8089 223 372 036 854 775 807
unsigned long018 446 744 073 709 551 615
int32_t-2 147 483 6482 147 483 647
uin32_t04 294 967 295
int64_t-9 223 372 036 854 775 8089 223 372 036 854 775 807
uint64_t018 446 744 073 709 551 615

64位程序上C語言整型數(shù)據(jù)類型的典型取值范圍

圖中的注意事項:
取值范圍不是對稱的———負數(shù)的范圍比整數(shù)的范圍大1.當我們考慮如何表示負數(shù)的時候,會看到為什么會是這樣子。

C數(shù)據(jù)類型最小值最大值
[signed] char-127127
unsigned char0255
short-3276732767
unsigned short065535
int-3276732767
unsigned065535
long-2 147 483 6472 147 483 647
unsigned long04 294 967 295
int32_t-2 147 483 6482 147 483 647
uin32_t04 294 967 295
int64_t-9 223 372 036 854 775 8089 223 372 036 854 775 807
uint64_t018 446 744 073 709 551 615

C語言的整型數(shù)據(jù)類型的保證的取值范圍。C語言標準要求這些數(shù)據(jù)類型必須至少具有這樣的取值范圍

C語言標準定義了每種數(shù)據(jù)類型必須能夠表示的最小的取值范圍。如上圖所示,它的取值范圍與32位和64位所示的典型實現(xiàn)一樣或者小一些。特別地,除了固定大小的數(shù)據(jù)類型是例外,我們看到它們只要求正數(shù)和負數(shù)的取值范圍是對稱的。此外,數(shù)據(jù)類型int可以用2個字節(jié)的數(shù)字來實現(xiàn)。這幾乎退到了16位機器的時代。還可以看到,long的大小可以用4個字節(jié)的數(shù)字來實現(xiàn),對32位程序來說這是很典型的。固定大小的數(shù)據(jù)類型保證數(shù)值的范圍與32位程序上C語言整型數(shù)據(jù)類型的典型取值范圍一致。包括負數(shù)與正數(shù)的不對稱性。

C語言支持多種整型數(shù)據(jù)類型——表示有限范圍的整數(shù)。如圖所示,其中給出了“典型”32位和64位機器的取值范圍。每種類型都能用關(guān)鍵字來指定大小,這些關(guān)鍵字包括c h a r 、 s h o r t 、 l o n g char、short、longchar、short、long,同時還可以指示被表示的數(shù)字是非負數(shù)(聲明為u n s i g n e d unsignedunsigned),或者可能是負數(shù)(默認即可)。為這些不同的大小分配的字節(jié)數(shù)可根據(jù)程序編譯為32位gcc -m32 prog.c或者64位gcc -m64 prog.c而有所不同。根據(jù)字節(jié)分配,不同的大小所能表示的值的范圍是不同的。特別注意,這里給出來的唯一一個與機器有關(guān)的取值范圍是大小指示符long的。大多數(shù)64位的機器使用8個字節(jié)的表示。比32位機器上使用的4個字節(jié)的表示的取值范圍大的多

補充:字數(shù)據(jù)大小

每臺計算機都有一個字長(word size),指明指針數(shù)據(jù)的標稱大?。╪ominal size)。
因為虛擬地址是以這樣的一個字來編碼的,所以字長決定的最重要的系統(tǒng)參數(shù)就是虛擬地址空間的最大大小。也就是說,對于一個字長為w ww位的機器而言,虛擬地址的范圍位0 − 2 w − 1 0 - 2^w-10−2w−1,程序最多訪問2 w 2^w2w個字節(jié)
最近這些年,出現(xiàn)了大規(guī)模的從32位字長機器到64位字長機器的遷移。這種情況首先出現(xiàn)在為大型科學(xué)和數(shù)據(jù)庫應(yīng)用設(shè)計的高端機器上,之后是臺式機和筆記本電腦,最近則出現(xiàn)在智能手機的處理器上。32位字長限制虛擬地址空間為4千兆字節(jié)(寫作4GB),也就是說,剛剛超過4 × 1 0 9 4\times10^94×109個字節(jié)。擴展到64位字長使得虛擬地址空間為16EB,大約是1.84 × 1 0 19 1.84\times 10^{19}1.84×1019字節(jié)

基本c數(shù)據(jù)類型的典型大小(以字節(jié)為單位)。分配的字節(jié)數(shù)受如何編譯的影響而變化。

三、看個例題

求 a 的 b 次方對 p 取模的值,其中 0≤a,b,c≤109, c>0

  • 用c++寫:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a,b,c;

int main(){
    cin >> a >> b >> c;
    ll ans = 1;
    while (b) {
        if(b&1) {
            ans = ans * a % c;
        } 
        a = a * a % c;
        b /= 2;  // 將指數(shù)右移一位
    }
    cout << ans % c << endl;
    
    return 0;
}

這里用long long類型來表示a,b,c三個數(shù),防止整數(shù)溢出,同時用到了快速冪算法,防止兩整數(shù)相乘的結(jié)果發(fā)生整數(shù)溢出。

快速冪算法通過對指數(shù) y 進行二進制拆分,將指數(shù)的冪運算轉(zhuǎn)化為多個底數(shù)的平方運算,從而減少了計算次數(shù),提高了算法效率。

  • 在 C 和 C++ 中,y & 1 表示對變量 y 的值和二進制數(shù) 1 進行按位與(AND)操作。具體來說,這個表達式會將 y 的二進制表示的最低位與 1 進行按位與運算,得到的結(jié)果為 0 或 1。

  • 如果 y 的最低位是 1,那么 y & 1 的結(jié)果就是 1;如果 y 的最低位是 0,那么 y & 1 的結(jié)果就是 0。

  • 這種操作通常用于判斷一個整數(shù)是奇數(shù)還是偶數(shù)。因為二進制數(shù)的最低位為 1 表示奇數(shù),為 0 表示偶數(shù),所以 y & 1 可以快速判斷 y 是奇數(shù)還是偶數(shù)。

  • c的寫法: (和c++只有一點點區(qū)別,文末補充)
#include<stdio.h>
int main(){
	long long a,b,c,d=1;
	scanf("%ld %ld %ld",&a,&b,&c);
	while(b){
		if(b&1)	d=d*a%c;
		a=a*a%c;
		b>>=1;
	}
	printf("%ld",d%c);
}
  • python的寫法
a, b, c = map(int, input().split())
print(pow(a, b, c))

但是如果python以下寫法,數(shù)值很大的時候就會發(fā)生溢出。

a, b, c = map(int, input().split())
ans = pow(a, b) % c
print(ans)

雖然Python 中的整數(shù)類型是動態(tài)的,不會存在固定的最大值,但如果結(jié)果超出了 Python 能表示的范圍,也會發(fā)生溢出。就比如pow(a, b) % c這一步,當a, b, c 很大的時候,也是會發(fā)生整數(shù)溢出。

但是python有個很方便的函數(shù),就是pow()的用法

pow(a, b, c)

具體參數(shù)含義如下:
a:底數(shù)
b:指數(shù)
c:模數(shù)

這個函數(shù)返回值為 (a**b) % c 的結(jié)果。

這個函數(shù)返回值為 (a**b) % c 的結(jié)果。

例如,pow(2, 3, 5) 將返回 3,因為 2 的 3 次方是 8,然后對 5 取模的結(jié)果是 3。

pow(a, b, c)函數(shù)在需要進行大數(shù)運算并對結(jié)果取模的情況下非常有用。

四、補充:scanf和cin的區(qū)別

scanf() 是 C 語言中的輸入函數(shù),而 cin 是 C++ 中的輸入流對象。它們之間有以下幾個區(qū)別:

  1. 語言:scanf() 是 C 語言的函數(shù),而 cin 是 C++ 的輸入流對象。

  2. 輸入方式:scanf() 是使用格式化字符串來指定輸入格式,可以通過不同的格式說明符(如 %d、%f、%s 等)來讀取不同類型的數(shù)據(jù)。而 cin 使用運算符重載和類型推斷來直接從標準輸入流中讀取數(shù)據(jù),不需要顯式指定輸入格式。

  3. 錯誤處理:scanf() 在讀取輸入時需要注意錯誤處理,因為它不能自動處理輸入格式不匹配或類型不正確的情況。而 cin 可以檢測到輸入類型不匹配等錯誤,并提供相應(yīng)的錯誤處理機制,比如將輸入流置于錯誤狀態(tài),清除錯誤標志等。

  4. 輸入緩沖:scanf() 函數(shù)對輸入的處理是基于緩沖區(qū)的,它會將輸入數(shù)據(jù)讀取到緩沖區(qū)中,然后根據(jù)格式字符串進行解析。而 cin 對象則是基于流的輸入,它會逐個字符地從輸入流中讀取并解析數(shù)據(jù),不需要緩沖區(qū)。

  5. 輸入分隔符:scanf() 默認以空格、制表符、換行符等作為輸入分隔符,可以通過格式化字符串來指定不同的分隔符。而 cin 默認以空格、制表符、換行符等作為輸入分隔符,但它還提供了更靈活的方式來處理不同的輸入分隔符。

總的來說,scanf() 是 C 語言中的函數(shù),使用格式化字符串來指定輸入格式,而 cin 是 C++ 中的輸入流對象,使用運算符重載和類型推斷來直接從標準輸入流中讀取數(shù)據(jù),并提供更靈活的錯誤處理機制。兩者在輸入方式、錯誤處理、緩沖處理和輸入分隔符上有所不同。

以上就是C/C++整數(shù)乘積的溢出問題的解決的詳細內(nèi)容,更多關(guān)于C/C++整數(shù)及乘積溢出的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C++實現(xiàn)LeetCode(139.拆分詞句)

    C++實現(xiàn)LeetCode(139.拆分詞句)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(139.拆分詞句),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • c語言內(nèi)存泄露示例解析

    c語言內(nèi)存泄露示例解析

    從1988年著名的莫里斯蠕蟲 攻擊到有關(guān) Flash Player 和其他關(guān)鍵的零售級程序的最新安全警報都與緩沖區(qū)溢出有關(guān):“大多數(shù)計算機安全漏洞都是緩沖區(qū)溢出”,Rodney Bates 在 2004 年寫道
    2013-09-09
  • VC使用編譯時間作為版本號標識的方法

    VC使用編譯時間作為版本號標識的方法

    這篇文章主要介紹了VC使用編譯時間作為版本號標識的方法,需要的朋友可以參考下
    2017-03-03
  • C語言各種變量的初始化方式

    C語言各種變量的初始化方式

    這篇文章主要介紹了C語言各種變量的初始化方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • 推箱子游戲C語言實現(xiàn)代碼

    推箱子游戲C語言實現(xiàn)代碼

    這篇文章主要為大家詳細介紹了推箱子游戲C語言實現(xiàn)代碼,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • C語言中find_package()的搜索路徑的實現(xiàn)

    C語言中find_package()的搜索路徑的實現(xiàn)

    本文主要介紹了C語言中find_package()的搜索路徑的實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • OpenCV識別圖像上的線條軌跡

    OpenCV識別圖像上的線條軌跡

    這篇文章主要為大家詳細介紹了OpenCV識別圖像上的線條軌跡,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • Matlab 數(shù)字圖像的濾波及邊緣檢測

    Matlab 數(shù)字圖像的濾波及邊緣檢測

    本文運用文字、代碼以及示例詳細介紹了數(shù)字圖像的濾波以及圖像的邊緣檢測,需要的朋友可以自己了解一下
    2021-08-08
  • Qt中多線程QThread、QThreadPool、QConCurrent三種方式對比分析

    Qt中多線程QThread、QThreadPool、QConCurrent三種方式對比分析

    QThread是Qt多線程的基石,本質(zhì)上是對操作系統(tǒng)原生線程的面向?qū)ο蠓庋b,本文介紹Qt中多線程QThread、QThreadPool、QConCurrent三種方式對比分析,感興趣的朋友一起看看吧
    2026-05-05
  • C語言實現(xiàn)輸出鏈表中倒數(shù)第k個節(jié)點

    C語言實現(xiàn)輸出鏈表中倒數(shù)第k個節(jié)點

    這篇文章主要介紹了C語言實現(xiàn)輸出鏈表中倒數(shù)第k個節(jié)點,主要涉及鏈表的遍歷操作,是數(shù)據(jù)結(jié)構(gòu)中鏈表的常見操作。需要的朋友可以參考下
    2014-09-09

最新評論

鸡西市| 循化| 上栗县| 江西省| 思南县| 石屏县| 汉源县| 句容市| 二手房| 涿鹿县| 斗六市| 郓城县| 休宁县| 留坝县| 东源县| 鄄城县| 永安市| 旬邑县| 蒙山县| 榆中县| 临猗县| 鄱阳县| 洱源县| 黄骅市| 全椒县| 铜梁县| 乐东| 潞城市| 金乡县| 宣武区| 辽源市| 廉江市| 江口县| 东港市| 江阴市| 太康县| 阿合奇县| 蒲城县| 肥乡县| 石嘴山市| 旌德县|