国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

GMP庫使用以及java中的BigInteger和BigDecimal

這篇具有很好參考價值的文章主要介紹了GMP庫使用以及java中的BigInteger和BigDecimal。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

一、GMP介紹和安裝

GMP library全稱是GNU Multiple Precision Arithmetic Library,即GNU高精度算術運算庫。在網(wǎng)絡安全技術領域中各種加密算法的軟件實現(xiàn)始終有一個共同話題是如何在普通的PC機上實現(xiàn)大數(shù)運算。普通的PC機內部字長最多時32位或64位,但各種加密算法中為了達到一定安全強度,都要求在128位、512位或1024位字長下進行加減乘除等數(shù)學運算,這叫做“大數(shù)運算”。

在此前提下,如何在普通的PC機上高效快速的實現(xiàn)大數(shù)運算成為加密算法在普通PC機上軟件實現(xiàn)的重要問題。如python等語言都內建大數(shù)計算機制,但C/C++語言既沒有內建大數(shù)運算機制,也沒有對應的標準庫實現(xiàn)。

GMP大數(shù)庫是GUN項目的一部分,誕生于1991年,作為一個任意精度的大整數(shù)運算庫,它包含了任意精度的整數(shù)、浮點數(shù)的各種基礎運算操作。它是一個C語言庫,并提供了C++的包裝類,主要應用于密碼學應用和研究、互聯(lián)網(wǎng)安全應用、代數(shù)系統(tǒng)、計算代數(shù)研究等。

GMP庫運行速度非???,官網(wǎng)上稱自己是地球上最快的大數(shù)庫,但GMP只提供了基礎數(shù)學運算,并沒有提供密碼學的相關運算。

1、在Mac上安裝

?到官網(wǎng)下載相應的包。

# Mac下方便解壓,直接下載 gmp-6.2.0.tar.xz 版本
# 解壓 
$ tar -xvf gmp-6.2.0.tar

# 編譯
$ cd gmp-6.2.0
$ ./configure --enable-cxx
$ make -j4  # 4 核心編譯速度更快 也可以直接 make

# 對編譯進行自測
$ make check

# 安裝 默認路徑為/usr/local
$ sudo make install

注:由于GMP是C語言庫,但也提供了C++的包裝類,在編譯時,如果要增加C++支持,./configure時加上--enable-cxx參數(shù),這樣才能使用c++庫gmpxx.h。

2、使用庫

鏈接到 libgmp 庫,使用選項 -lgmp:

gcc myprogram.c -lgmp

c++函數(shù)在 libgmpxx 庫中,因此需要額外的編譯選項:

g++ mycxxprog.cc -lgmpxx -lgmp

3、示例

1)整型運算:

testgmp.cpp:

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

int main()
{
    mpz_t a,b,c,d;  // define
    mpz_init(a);  // initialize
    mpz_init(b);
    mpz_init(c);
    mpz_init(d);
    gmp_scanf("%Zd%Zd",a,b);  // input
    mpz_add(c,a,b);  // compute c = a + b
    gmp_printf("%Zd\n",c);  // output
    mpz_mul(d,a,b);  // compute d = a * b
    gmp_printf("%Zd\n",d);  // output
    mpz_clear(a);  // clear memory
    mpz_clear(b);
    mpz_clear(c);
    mpz_clear(d);
    return 0;
}

編譯、運行

# 編譯
$ g++ -o testgmp.out testgmp.cpp -lgmpxx -lgmp

# 運行
$ ./testgmp.out
324327543564685049860389045809768327483265873264578346593489
100000000000000000000000000000000000000000000000000000000001

?輸出:

424327543564685049860389045809768327483265873264578346593490
3243275435646850498603890458097683274832658732645783465934922432754356468504986038904580976832748326587326457

2)浮點型運算:

testgmp2.cpp

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

int main()
{
    mpf_set_default_prec(64); // 默認精度,即小數(shù)點后精確多少位
    mpf_t a,b,c,d;  // define

    mpf_init(a);  // initialize
    mpf_init(b);
    mpf_init(c);
    mpf_init(d);

    gmp_scanf("%Ff%Ff",a,b);  // input
    mpf_add(c,a,b);  // compute c = a + b
    gmp_printf("%Ff\n",c);  // output
    mpf_mul(d,a,b);  // compute d = a * b
    gmp_printf("%Ff\n",d);  // output
    mpf_clear(a);  // clear memory
    mpf_clear(b);
    mpf_clear(c);
    mpf_clear(d);
    return 0;
}

?編譯、運行

$ g++ -o testgmp2.out testgmp2.cpp -lgmpxx -lgmp
$ ./testgmp2.out
9876543.123456
123456.987654

輸出

10000000.111110
1219328262456.705990

?4、GMP庫介紹

  • 在線文檔:Top (GNU MP 6.2.1)
  • 官方手冊:https://gmplib.org/gmp-man-6.2.1.pdf

4.1)數(shù)據(jù)類型:

  • mpz_t(整數(shù))?? ?mpz_開頭
  • mpq_t(有理數(shù))?? ?mpq_開頭
  • mpf_t(浮點數(shù))?? ?mpf_開頭

4.2)使用步驟:(以浮點型為例)

1)聲明變量:

mpf_t fnum;

2)初始化變量:

mpf_init(fnum); //或mpf_init(fnum,20),此函數(shù)指針對類型mpf_t有效

3)變量賦值:

mpf_set_str(fnum,"1.23",10);?? ?//以10為進制數(shù),表示浮點數(shù)的字符串來賦值fnum

//mpf_set_str的原型
int mpf_init_set_str (mpf_ptr, const char *, int);
其中三個參數(shù)表示為多精度浮點數(shù)變量、字符串、進制。

4)變量計算:

mpf_mul(fnum,fnum,tmp);?? ?//fnum和tmp都是mpf_t類型的變量

5)釋放變量:

mpf_clear(fnum);?? ?

?4.3)常用方法:

  • 加法:void mpz_add(mpz_t rop, mpz_t op1, mpz_t op2); ?//rop = op1 + op2
  • 減法:void mpz_sub(mpz_t rop, mpz_t op1, mpz_t op2); ?//rop = op1 - op2
  • 乘法:void mpz_mul(mpz_t rop, mpz_t op1, mpz_t op2); //rop = op1 * op2
  • 除法:void mpz_cdiv_q (mpz_t q, mpz_t n, mpz_t d); ?//q = n/d,這個有很多種類型,具體的看使用手冊
  • 冪運算:void mpz_pow_ui (mpz_t rop, mpz_t base, unsigned long int exp); ?//rop = base^exp
  • 開方:void mpz_sqrt (mpz_t rop, mpz_t op); //rop = op開方的向下取整

5、應用:(RSA加密)

#include <iostream>
#include <gmpxx.h>
#include <cstdlib>

using namespace std;

mpz_class randbits(int bits) // base = 2
{
    gmp_randclass a(gmp_randinit_default);
    a.seed(rand());
    mpz_class l(bits);
    return a.get_z_bits(l);
}

inline mpz_class randprime(int bits)
{
    mpz_class a = randbits(bits);
    mpz_class ret;
    mpz_nextprime(ret.get_mpz_t(), a.get_mpz_t());
    return ret;
}

void setKey(mpz_class &n, mpz_class &e, mpz_class &d, const int nbits, int ebits = 16)
{
    if (nbits / 2 <= ebits)
    {
        ebits = nbits / 2;
    }
    mpz_class p = randprime(nbits / 2); //隨機取p
    mpz_class q = randprime(nbits / 2); //隨機取q
    n = q * p;                          //計算n=p*q
    mpz_class fn = (p - 1) * (q - 1);   //計算歐拉數(shù)
    mpz_class gcd;
    do
    {
        e = randprime(ebits);           //隨機取e
        mpz_gcd(gcd.get_mpz_t(), e.get_mpz_t(), fn.get_mpz_t());       //判斷gcd(e,fn)=1是否成立
    } while (gcd != 1);
    //mpz_gcdext(g, s, t, a, b): g = as + bt
    mpz_gcdext(p.get_mpz_t(), d.get_mpz_t(), q.get_mpz_t(), e.get_mpz_t(), fn.get_mpz_t()); //計算d=e^{-1} mod fn
}

inline mpz_class encrypt(const mpz_class &m, const mpz_class &e, const mpz_class &n)
{
    mpz_class ret;
    mpz_powm(ret.get_mpz_t(), m.get_mpz_t(), e.get_mpz_t(), n.get_mpz_t()); //ret=m^e mod n
    return ret;
}

inline mpz_class decrypt(const mpz_class &c, const mpz_class &d, const mpz_class &n)
{
    return encrypt(c, d, n);    //m=c^d mod n
}

int main()
{
    int nbits;
    cout << "輸入大數(shù)比特數(shù):";
    cin >> nbits;
    mpz_class n, e, d;
    setKey(n, e, d, nbits);         //密鑰生成
    cout << "公鑰:(e=" << e.get_str() << ", n=" << n.get_str() << ")" << endl;
    cout << "私鑰:(d=" << d.get_str() << ", n=" << n.get_str() << ")" << endl;

    cout << "輸入加密數(shù)據(jù):";
    string s;
    cin >> s;

    mpz_class m(s);
    mpz_class c;
    c = encrypt(m, e, n);       //加密
    cout << "加密后:" << c.get_str() << endl;
    c = decrypt(c, d, n);       //解密
    cout << "解密后:" << c.get_str() << endl;
    if (c == m)
        cout << "加/解密成功!" << endl
             << endl;
    else
        cout << "加/解密失敗!" << endl
             << endl;

    string q;
    cout << "是否繼續(xù)(Y/N):";
    cin >> q;
    if (q == "y" || q == "Y")
        main();
    return 0;
}

二、java中的BigInteger和BigDecimal

1、BigInteger:

在Java中,由CPU原生提供的整型最大范圍是64位long型整數(shù)。使用long型整數(shù)可以直接通過CPU指令進行計算,速度非??臁?/p>

如果我們使用的整數(shù)范圍超過了long型怎么辦?這個時候,就只能用軟件來模擬一個大整數(shù)。java.math.BigInteger就是用來表示任意大小的整數(shù)。BigInteger內部用一個int[]數(shù)組來模擬一個非常大的整數(shù)。和long型整數(shù)運算比,BigInteger不會有范圍限制,但缺點是速度比較慢。

private static void test() {
	BigInteger a = new BigInteger("324327543564685049860389045809768327483265873264578346593489");
	BigInteger b = new BigInteger("100000000000000000000000000000000000000000000000000000000001");
	
	BigInteger c = a.add(b);
	BigInteger d = a.multiply(b);
	System.out.println(c.toString());//424327543564685049860389045809768327483265873264578346593490
	System.out.println(d.toString());//32432754356468504986038904580976832748326587326457834659349224327543564685049860389045809768327483265873264578346593489
}

2、BigDecimal:

和BigInteger類似,BigDecimal可以表示一個任意大小且精度完全準確的浮點數(shù)。如果查看BigDecimal的源碼,可以發(fā)現(xiàn),實際上一個BigDecimal是通過一個BigInteger和一個scale來表示的,即BigInteger表示一個完整的整數(shù),而scale表示小數(shù)位數(shù)。

1)除法運算:

對BigDecimal做加、減、乘時,精度不會丟失,但是做除法時,存在無法除盡的情況,這時,就必須指定精度以及如何進行截斷:

BigDecimal d1 = new BigDecimal("123.456");
BigDecimal d2 = new BigDecimal("23.456789");
BigDecimal d3 = d1.divide(d2, 10, RoundingMode.HALF_UP); // 保留10位小數(shù)并四舍五入
BigDecimal d4 = d1.divide(d2); // 報錯:ArithmeticException,因為除不盡

2)比較:

在比較兩個BigDecimal的值是否相等時,要特別注意,使用equals()方法不但要求兩個BigDecimal的值相等,還要求它們的scale()相等:

BigDecimal d1 = new BigDecimal("123.456");
BigDecimal d2 = new BigDecimal("123.45600");
System.out.println(d1.equals(d2)); // false,因為scale不同
System.out.println(d1.equals(d2.stripTrailingZeros())); // true,因為d2去除尾部0后scale變?yōu)?
System.out.println(d1.compareTo(d2)); // 0

所以,必須使用compareTo()方法來比較,它根據(jù)兩個值的大小分別返回負數(shù)、正數(shù)和0,分別表示小于、大于和等于。

3)求余數(shù)

BigDecimal n = new BigDecimal("12.345");
BigDecimal m = new BigDecimal("0.12");
BigDecimal[] dr = n.divideAndRemainder(m);
System.out.println(dr[0]); // 102
System.out.println(dr[1]); // 0.105

?調用divideAndRemainder()方法時,返回的數(shù)組包含兩個BigDecimal,分別是商和余數(shù),其中商總是整數(shù),余數(shù)不會大于除數(shù)。我們可以利用這個方法判斷兩個BigDecimal是否是整數(shù)倍數(shù):

BigDecimal n = new BigDecimal("12.75");
BigDecimal m = new BigDecimal("0.15");
BigDecimal[] dr = n.divideAndRemainder(m);
if (dr[1].signum() == 0) {
    // n是m的整數(shù)倍
}



https://www.cnblogs.com/pam-sh/p/17368429.html

C/C++ gmp庫之浮點數(shù)實例 | 織夢先生文章來源地址http://www.zghlxwxcb.cn/news/detail-474020.html

到了這里,關于GMP庫使用以及java中的BigInteger和BigDecimal的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • MAC中的JAVA安裝以及環(huán)境配置

    MAC中的JAVA安裝以及環(huán)境配置

    MAC中的JAVA安裝以及環(huán)境配置 Mac OS安裝JDK以及配置環(huán)境0基礎適宜 目錄: 一、JDK的下載以及安裝 二、安裝路徑以及環(huán)境配置 三、使配置生效 首先是到Oracle官網(wǎng)下載適合的JDK安裝包,可以根據(jù)需要來選擇對應的安裝包 官網(wǎng)下載鏈接: Java Downloads | Oracle 點擊上方鏈接即可跳轉到

    2024年02月08日
    瀏覽(37)
  • 日常BUG——Java使用Bigdecimal類型報錯

    日常BUG——Java使用Bigdecimal類型報錯

    ?? 作 ? ??????? 者 :是江迪呀 ?? 本文 : 日常BUG 、 BUG 、 問題分析 ?? 每日?? 一言 : 存在錯誤說明你在進步! 直接上代碼: 報錯內容: 原來JAVA中如果用 BigDecimal 做除法的時候一定要在divide方法中傳遞第二個參數(shù),定義精確到小數(shù)點后幾位,否則在不整除

    2024年02月13日
    瀏覽(34)
  • Linux 中的以太網(wǎng)管理,以及udhcpc介紹和使用步驟

    在Linux中, udhcpc 是一個用于動態(tài)獲取IP地址的工具,通常用于DHCP(Dynamic Host Configuration Protocol)網(wǎng)絡配置。它是BusyBox工具集中的一部分,用于從DHCP服務器獲取IP地址、網(wǎng)關、DNS服務器等網(wǎng)絡配置信息。 以下是 udhcpc 的基本介紹和使用流程: 1. 安裝 udhcpc : udhcpc 通常是與Bus

    2024年04月22日
    瀏覽(52)
  • java BigDecimal使用(小數(shù)點,字符串等轉換)

    Java中提供了操作大數(shù)字(超過 16位 有效位)的類, 即 java.math.BigInteger 類和 java.math.BigDecimal 類,用于高精度計算。 float和Double只能用來做科學計算、工程計算等;在商業(yè)計算中,對數(shù)字精度要求較高(例如貨幣值),必須使用 BigInteger 類和 BigDecimal 類,它支持任何精度的定點數(shù),

    2024年02月14日
    瀏覽(17)
  • Java開發(fā)手冊中為什么禁止使用BigDecimal的equals方法做等值比較已經(jīng)為什么禁止使用double直接構造BigDecimal

    Java開發(fā)手冊中為什么禁止使用BigDecimal的equals方法做等值比較已經(jīng)為什么禁止使用double直接構造BigDecimal

    阿里Java開發(fā)手冊嵩山版中明確指出: 1、BigDecimal的等值比較應使用compareTo()方法,而不是equals()方法 equals()方法會比較值和精度(1.0與1.00返回結果為false),而compareTo()則會忽略精度 2、禁止使用構造方法BigDecimal(double)的方式把double值轉換為BigDecimal對象 BigDecimal(double)存在精度損

    2024年02月07日
    瀏覽(34)
  • 66. 加一(Java):BigInteger

    給定一個由 整數(shù) 組成的 非空 數(shù)組所表示的非負整數(shù),在該數(shù)的基礎上加一。 最高位數(shù)字存放在數(shù)組的首位, 數(shù)組中每個元素只存儲單個數(shù)字。 你可以假設除了整數(shù) 0 之外,這個整數(shù)不會以零開頭。 digits = [4,3,2,1] [4,3,2,2] 解釋:輸入數(shù)組表示數(shù)字 4321。 BigInteger 是Java中的一

    2024年01月25日
    瀏覽(17)
  • ElasticSearch之IK分詞器安裝以及使用介紹

    ElasticSearch之IK分詞器安裝以及使用介紹

    elasticsearch 默認的內置分詞器對中文的分詞效果可能并不理想,因為它們主要是針對英文等拉丁語系的文本設計的。如果要在中文文本上獲得更好的分詞效果,我們可以考慮使用中文專用的分詞器。 IK 分詞器是一個開源的中文分詞器插件,特別為 Elasticsearch 設計和優(yōu)化。它在

    2024年02月13日
    瀏覽(30)
  • 阿里云免費SSL證書的簡單介紹以及安裝使用

    阿里云免費SSL證書的簡單介紹以及安裝使用

    qquad 阿里云SSL證書服務提供免費版SSL證書(即免費證書)和付費版SSL證書(即付費證書)。免費證書主要以公益目的提供給阿里云用戶使用,便于個人或企業(yè)用戶在網(wǎng)站建設之初或業(yè)務需要使用HTTPS通信時進行測試。 qquad 免費證書一般僅用于個人網(wǎng)站或測試使用,不建議業(yè)

    2024年02月06日
    瀏覽(22)
  • JSON 基本語法以及在Java 中的使用

    JSON(JavaScript Object Notation)是一種輕量級的數(shù)據(jù)交互格式。它去除了所有 JavaScript 執(zhí)行代碼,只保留 JavaScript 的對象格式。 它基于 ECMAScript (歐洲計算機協(xié)會制定的 js 規(guī)范)的一個子集,采用完全獨立于編程語言的文本格式來存儲和表示數(shù)據(jù)。 JSON適合表示層次結構,JSON采用鍵

    2024年01月23日
    瀏覽(33)
  • snmp trap 與snmp相關介紹、安裝、命令以及Trap的發(fā)送與接收java實現(xiàn)

    snmp trap 與snmp相關介紹、安裝、命令以及Trap的發(fā)送與接收java實現(xiàn)

    1.1、什么是Snmp SNMP是英文\\\"Simple Network Management Protocol\\\"的縮寫,中文意思是\\\"簡單網(wǎng)絡管理協(xié)議\\\"。SNMP是一種簡單網(wǎng)絡管理協(xié)議,它屬于TCP/IP五層協(xié)議中的應用層協(xié)議,用于網(wǎng)絡管理的協(xié)議。SNMP主要用于網(wǎng)絡設備的管理。由于SNMP協(xié)議簡單可靠 ,受到了眾多廠商的歡迎,成為了目

    2024年02月02日
    瀏覽(43)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包