MPIR VS2017配置及使用
MPIR VS2017配置及使用(官方文档版)
因为要使用大数运算,自己在GitHub上找到star最多的c++版本BigNumber用string实现,但是在实际使用过程中,发现其运算能力有限,主要是乘法和除法实现的思路是循环加和循环减,而我的数据比较大,所以非常耗时。之后查到大家使用最多的是gmp,然而官方教程是用在Linux,查到可以用g++实现这部分的编译,但是在VS2017 的配置中又出现了问题。查找如何配置的过程中发现了how to install gmp for c on VS,推荐使用MPIR来实现大数运算,这个库是gmp在win下可以运行的版本。
下面我将按照官方文档安装及配置。
emmmm,实际配置过程各种问题,比如不能测试之类的。我自己的配置顺序在第二节。
参考文档 https://www.exploringbinary.com/how-to-install-and-run-gmp-on-windows-using-mpir/
所需
YASM相关(64位)
下载压缩包Win64 VS2010 .zip ,解压,按照文档要求This assembler (vsyasm.exe, NOT yasm.exe) should be placed in the directory C:\ProgramFiles\yasm. 或者,如果环境变量’YASMPATH’给出了它的位置,可以将vsyasm.exe放在别处。
压缩包中也有readme.txt,下面大概说下这个内容。
yasm readme
说明:我并未按照这个方式,而是一路顺着官方文档的指导。
YASM版本vsyasm.exe专门用于Visual Studio 2010。要告诉Visual Studio在哪里可以找到vsyasm.exe,可以将环境变量YASMPATH设置为vsyasm.exe所在目录的绝对路径(这个路径应该包括最后的反斜杠)。或者,可以找到VC ++编译器二进制文件所在的目录,并将vsyasm.exe二进制文件的副本放在这些目录中。 64位Windows上的典型位置是:
C:\Program Files(x86)\Microsoft Visual Studio 10.0\VC\bin.
若要在Visual Studio 2010中使用新的自定义工具,需要将三个文件(yasm.props,yasm.targets和yasm.xml)的副本放置到Visual Studio构建自定义过程可以找到它们的位置。有几个方法这样做:
-
将这些文件放在MSBUILD自定义目录中,该目录通常位于: C:\Program Files(x86)\MSBuild\Microsoft.Cpp\v4.0\BuildCustomizations
-
将它们放在一个方便的位置,并在“工具|选项”菜单中的Visual Studio“项目和解决方案| VC ++项目设置”项中的“属性”中设置此路径;
-
将它们放在一个方便的位置,并在“属性”对话框中设置此路径(稍后讨论)。
要在项目中使用YASM,请在解决方案资源管理器中右键单击项目,然后选择“属性”。这将为您提供一个对话框,允许您选择YASM作为汇编程序(请注意,汇编程序文件需要具有扩展名’.asm’)。如果您使用了选项c。在上面,您需要让对话使用对话框下方的“查找现有”按钮找到它们。
要使用YASM汇编文件,请选择文件的“属性页”,然后在“工具”对话框条目中选择“Yasm汇编程序”。然后单击“应用”,将出现另一个属性页面条目,并启用YASM设置。
Building MPIR
通过双击适当的文件mpir.sln启动MPIR的构建
MPIR根目录下的子目录:
- Visual Studio 2012:mpir / build.vc11 / mpir.sln
- Visual Studio 2013:mpir / build.vc12 / mpir.sln
- Visual Studio 2015:mpir / build.vc14 / mpir.sln
- Visual Studio 2017:mpir / build.vc15 / mpir.sln
然后,Visual Studio将显示一个单独的构建项目的列表
可以构建适当版本的MPIR。 例如,典型的项目列表是
名称 | 说明 |
---|---|
dll_mpir_gc | 标准DLL,没有汇编程序(win32和x64) |
dll_mpir_p3 | 动态库,含32位汇编代码,奔腾3 |
lib_mpir_p3 | 汇编静态库,奔腾3,32位 |
lib_mpir_core2 | 汇编静态库,core2,x64 |
dll_mpir_core2 | 汇编动态库,core2,x64 |
MPIR既可以构建为静态库,也可以构建为DLL。 DLL将包含MPIR的C和C ++功能,但静态库将仅包含C功能,因此在本例中为项目:
lib_mpir_cxx :the MPIRXX C++ static library (win32 and x64)
也应该构建为提供MPIR C ++静态库(‘MPICXX’)。
在构建项目之前,应将Visual Studio设置为所需的配置(debug or release)和所需的目标体系结构(win32或x64)。 构建过程将输出文件放入两个子目录之一:
- mpir/lib
- mpir/dll
取决于是否已构建静态库或DLL版本。
其他汇编程序优化版本
用于MPIR的Visual Studio构建最初提供了一小组汇编程序优化项目,但还有更多可用,可以通过运行mpir \ build-vc目录中的Python程序mpir_config.py 来获得。 所需的值取决于使用的Visual Studio版本,如下所示:
- Visual Studio 2012: 11
- Visual Studio 2013: 12
- Visual Studio 2015: 14
- Visual Studio 2017: 15
此程序必须在Visual Studio之前运行,它提供了可用的所有MPIR汇编程序优化版本的列表。 可以选择任意数量的版本,然后通过双击mpir.sln随后打开Visual Studio时可以使用这些版本。
测试Visual Studio的MPIR版本
通过双击相应的解决方案文件,开始测试库的版本:
Visual Studio 2012:mpir / build.vc11 / mpir-tests.sln
Visual Studio 2013:mpir / build.vc12 / mpir-tests.sln
Visual Studio 2015:mpir / build.vc14 / mpir-tests.sln
Visual Studio 2017:mpir / build.vc15 / mpir-tests.sln
测试总是在最后一个版本的MPIR上运行,重要的是构建测试的配置集(Release或Debug,win32或x64)与用于构建MPIR的配置相同。 在测试MPIR的静态库版本时,必须构建C(mpir.lib)和C ++ mpirxx.lib。 加载后会有一大堆测试项目开始:
Solution ‘mpir-tests’ (202 projects)
add-test-lib
bswap
constants
…
应首先选择和构建项目“add-test-lib”,然后可以选择整个解决方案(即上面显示的第一行)来构建所有测试。 构建完成后,通过在相应的Visual Studio构建子目录中执行Python程序run-tests.py来运行测试,例如,对于Visual Studio 2017:
mpir/build.vc15/mpir-tests/run-tests.py
我自己的配置过程(VS 2017 社区版可行)
dll_mpir_gc.sln
- 首先是SDK的问题,项目重定向为自己系统的SDK,原来MPIR中要求的是8.1
- 不知道为什么在生成lib和dll之后,dll_mpir_gc就运行失败了,但是好在库已经拿到了,用这个就行了。
- 将库和相关头文件的目录添加到新的项目里,测试下可以运行就行了。
配置
在这里,我新建了一个项目,在项目里面创建include和lib两个文件夹,然后将config.h,gmp-impl.h,gmp-mparam.h,gmp.h,longlong.h,longlong_post.h,longlong_pre.h,mpir.h,mpirxx.h,randmt.h放入/include(可能有些.h并不需要,我没细看),将生成的mpir.lib放入/lib中。
项目配置:VC++目录——包含目录,库目录;
链接器-输入——附加依赖项
测试
#include <iostream>
using namespace std;
#pragma warning(disable: 4800)
#include <mpirxx.h>
#pragma warning(default: 4800)
int main(int argc, char *argv[])
{
mpz_class aBigPO2, d;
d = "3740917590749349571";
aBigPO2 = 1073741824; //2^30
//aBigPO2 *= aBigPO2; //2^60
//aBigPO2 *= aBigPO2; //2^120
//aBigPO2 *= aBigPO2; //2^240
//aBigPO2 *= aBigPO2; //2^480
//aBigPO2 *= aBigPO2; //2^960
//aBigPO2 *= aBigPO2; //2^1920
aBigPO2 = d / aBigPO2;
cout << aBigPO2 << endl;
}