To perform arbitrary-precision arithmetic in C and C++ programs on Windows, I use GMP. In particular, I use MPIR, a Windows port of GMP. MPIR is a simple alternative to using GMP under Cygwin or MinGW.
I will show you how to install MPIR in Microsoft Visual C++ as a static, 32-bit library. I will also show you how to install the optional C++ interface — also as a static, 32-bit library. I will provide two example C programs that call the GMP integer and floating-point functions, and two equivalent C++ programs — programs that use the same GMP functions, only indirectly through the C++ interface.
1. Download What You Need
To install MPIR and run it under Visual C++ as I have, you’ll need four things:
- Microsoft Visual C++ (I use Visual C++ 2008 Express Edition).
- A file archiver (I use 7-Zip).
- The MPIR source code and Visual C++ solution (I use mpir-1.3.1.tar.gz, which is based on GMP version 4.2.1).
- The Yasm assembler (I use yasm-0.8.0-win32.exe).
(I won’t describe how to install Visual C++ or 7-zip.)
2. Prepare to Build MPIR
MPIR must be built with Visual C++; to prepare for that, do the following:
- From mpir-1.3.1.tar.gz, use your file archiver to extract mpir-1.3.1.tar; from mpir-1.3.1.tar, extract folder mpir-1.3.1.
- Copy \mpir-1.3.1\build.vc9\yasm.rules to the Visual C++ project defaults directory (mine is C:\Program Files\Microsoft Visual Studio 9.0\VC\VCProjectDefaults\).
- Rename file yasm-0.8.0-win32.exe to yasm.exe.
- Move yasm.exe to the Visual C++ binary directory (mine is C:\Program Files\Microsoft Visual Studio 9.0\VC\bin\).
3. Build MPIR
Here’s how to build MPIR as a static Win32 library:
- Open the MPIR Visual C++ solution \mpir-1.3.1\build.vc9\mpir.sln.
You get the following error message if you are using Visual Studio Express:
The project consists entirely of configurations that require support for platforms which are not installed on this machine. The project cannot be loaded.
This message is referring to the 64-bit projects, which we won’t be using anyway. Hit ‘Enter’ to ignore (do this eight times — one for each 64-bit project in the solution.)
- Right click on “Solution ‘mpir’ (14 projects)”, select “Properties” and then click on “Configuration Properties” and then click on “Configuration Manager”. In the box labeled “Active solution configuration” select “Release” and then click “Close” and then click “OK”.
- Build the version of the library you want by right clicking on the project name and selecting “Build” (I built lib_mpir_p4, labeled in the readme file as the “MPIR library using Pentium IV assembler”).
A successful build of lib_mpir_p4, which should take less than two minutes, gives this message:
Build: 6 succeeded, 0 failed, 0 up-to-date, 0 skipped
(You can ignore the compiler warning messages.)
- Optional: for C++ interface only: Build the C++ interface by right clicking on project lib_mpir_cxx and selecting “Build” (again, ignore the compiler warning messages).
4. Install the MPIR Library in Visual C++
To install MPIR in Visual C++, you need to copy three files from the MPIR build directory into corresponding Visual C++ directories:
- Copy files mpir.lib and mpir.pdb from
\mpir-1.3.1\build.vc9\lib_mpir_p4\Win32\Release\
to the Visual C++ library directory
C:\Program Files\Microsoft Visual Studio 9.0\VC\lib\.
- Copy \mpir-1.3.1\build.vc9\lib_mpir_p4\Win32\Release\mpir.h
to the Visual C++ include directory
C:\Program Files\Microsoft Visual Studio 9.0\VC\include\.
Optional: for C++ interface only: To install the library for the C++ interface, you need to copy three files from the MPIR build directory into corresponding Visual C++ directories:
- Copy files mpirxx.lib and mpirxx.pdb from
\mpir-1.3.1\build.vc9\lib_mpir_cxx\Win32\Release\
to the Visual C++ library directory
C:\Program Files\Microsoft Visual Studio 9.0\VC\lib\.
- Copy \mpir-1.3.1\build.vc9\lib_mpir_cxx\Win32\Release\mpirxx.h
to the Visual C++ include directory
C:\Program Files\Microsoft Visual Studio 9.0\VC\include\.
(Unless you want to build another library, you can delete the folder mpir-1.3.1 at this point, and perhaps file mpir-1.3.1.tar.gz too. You might also want to wait until you run the test programs below.)
5. Configure Your Visual C++ Project to Use MPIR
- Open an existing Visual C++ solution or create a new one.
- Right click on the project name and select “Properties”. Then click “Configuration Properties”, then click “Linker”, and then click “Command Line”. In the “Additional options” box, enter “mpir.lib” and click OK.
Optional: for C++ interface only: Also add “mpirxx.lib” to the command line:
- Right click on the project name and select “Properties”. Then click “Configuration Properties”, then click “C/C++”, and then click “Code Generation”. In the “Runtime Library” pulldown menu, select “Multi-threaded (/MT)” and click OK. This takes care of the linker warning message you would otherwise get:
LINK : warning LNK4098: defaultlib ‘LIBCMT’ conflicts with use of other libs; use /NODEFAULTLIB:library
Writing a C/C++ Program that Uses the Standard GMP Interface
To access the GMP functions through their standard interface from your C/C++ source code, you must include the file “mpir.h”, as follows:
#include <mpir.h>
(A vanilla GMP program would have the line “#include <gmp.h>” instead; other than this, there are no source code differences.)
The MPIR GMP functions are documented in the MPIR manual, which is essentially the same document as the GMP manual.
Here are two C programs I wrote that you can use to test out the standard GMP interface: one uses some integer functions, and one uses some floating-point functions:
C Program Using GMP Integers Through the Standard Interface
#include <stdio.h> #include <mpir.h> int main (int argc, char *argv[]) { mpz_t aBigPO2; mpz_init(aBigPO2); mpz_set_ui(aBigPO2, 1073741824); //2^30 mpz_mul(aBigPO2,aBigPO2,aBigPO2); //2^60 mpz_mul(aBigPO2,aBigPO2,aBigPO2); //2^120 mpz_mul(aBigPO2,aBigPO2,aBigPO2); //2^240 mpz_mul(aBigPO2,aBigPO2,aBigPO2); //2^480 mpz_mul(aBigPO2,aBigPO2,aBigPO2); //2^960 mpz_mul(aBigPO2,aBigPO2,aBigPO2); //2^1920 mpz_out_str(stdout,10,aBigPO2); printf ("\n"); mpz_clear(aBigPO2); }
This prints out 21920:
94971145180789141405469863695884969990692470634685116742800956330585166286696033875105787408321105016172948848387979899381078776548058719274153038481919330076987462588432197778346974895637755344856609332899271782077461008182119361693275785914457910967149403472811089067095457018656127063791202559391107981952290497413671516189054715030212151457729925746607341068107450556036691253445520158175442766273106804460580598760425795931407058821363012979657287013264796313022267140908229491284859997425339970007394059640858536497878915778164024704513828250590897948604589281308443672576
(I verified this with PARI/GP).
C Program Using GMP Floating-Point Numbers Through the Standard Interface
#include <stdio.h> #include <mpir.h> int main (int argc, char *argv[]) { mpf_t aSmallPO2; mpf_init2(aSmallPO2,4449); //Set precision to 4449 bits mpf_set_d (aSmallPO2,0.000000000931322574615478515625); //2^-30 mpf_mul(aSmallPO2,aSmallPO2,aSmallPO2); //2^-60 mpf_mul(aSmallPO2,aSmallPO2,aSmallPO2); //2^-120 mpf_mul(aSmallPO2,aSmallPO2,aSmallPO2); //2^-240 mpf_mul(aSmallPO2,aSmallPO2,aSmallPO2); //2^-480 mpf_mul(aSmallPO2,aSmallPO2,aSmallPO2); //2^-960 mpf_mul(aSmallPO2,aSmallPO2,aSmallPO2); //2^-1920 mpf_out_str (stdout,10,0,aSmallPO2); printf ("\n"); mpf_clear(aSmallPO2); }
In case you are wondering, 4449 bits of precision is the minimum needed to print all the digits of 2-1920, which is:
0.10529513970757941370610747782095090628278032322332406685248932058897487219070703960159412040312324958550178793587321231496166104341706794282781804465303264220467370978600946532498508432543965246414865877765268438334467392843186701182578047022952222095279213542847547625013806063593981326312438954782159919569806945780558159983139494516214892022781358701106426838049878064090625594920050022451240382009550462442380576658723954500997837640072880232154236046343680085877727078528072722123195366215111990411019537148197442558048635218274092172396907226681705608220792266895576870551894550762902880978557369092132249954500903556336262479360506670537902070512869428970881638135729845035256195565406246915590828484638991615219052004055944813329481598847969387027700161783333580357966554786123158354267457962223811465954330911610564228730020236245605524128583533967685249775398427450933606825973311143113749366383842644503177277545696627287282123055942162951336932925420375112836461462120338241148915081655517081206432234061188196029609231357524022063469959597949051896076865883172740955991670305216873490456538967283758977304086971554554058064166260468764067261026647814993777560662012132796935609524129908146753623680552693333706194072338489699818137150849777160489153948872988676360548263714707910434915092735830288717124858521856367588043212890625e-577
(I verified this with PARI/GP).
Writing a C++ Program that Uses the GMP C++ Interface
(To use the C++ interface you will have had to have followed the build steps labeled ‘optional’ above.)
To access the GMP functions through their C++ interface, you must include the file “mpirxx.h”, as follows:
#include <mpirxx.h>
(A vanilla GMP program would have the line “#include <gmpxx.h>” instead.)
Also, your source code will require this additional line, if you want to remove the compiler warnings due to mpirxx.h:
#pragma warning(disable: 4800)
Without this, you will get about a dozen warning messages like this:
c:\program files\microsoft visual studio 9.0\vc\include\mpirxx.h(1610) : warning C4800: ‘int’ : forcing value to bool ‘true’ or ‘false’ (performance warning)
The MPIR GMP C++ interface is documented in the MPIR manual (and the GMP manual).
Here are two C++ programs I wrote that you can use to test out the GMP C++ interface: they are the equivalent of the two C programs above, except they’re expressed much more naturally (as to be expected in a C++ program):
C++ Program Using GMP Integers Through the C++ Interface
#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; 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 cout << aBigPO2 << endl; }
(This gives the same output as the C program above.)
C++ Program Using GMP Floating-Point Numbers Through the C++ Interface
#include <iostream> #include <iomanip> using namespace std; #pragma warning(disable: 4800) #include <mpirxx.h> #pragma warning(default: 4800) int main (int argc, char *argv[]) { mpf_class aSmallPO2(0,4449); //Init to 0, precision 4449 bits aSmallPO2 = 0.000000000931322574615478515625; //2^-30 aSmallPO2*=aSmallPO2; //2^-60 aSmallPO2*=aSmallPO2; //2^-120 aSmallPO2*=aSmallPO2; //2^-240 aSmallPO2*=aSmallPO2; //2^-480 aSmallPO2*=aSmallPO2; //2^-960 aSmallPO2*=aSmallPO2; //2^-1920 cout << setprecision (1343) << aSmallPO2 << endl; }
The value of 1343 to setprecision is the precision in decimal digits.
The output differs slightly from it’s corresponding C program (the number is shifted one place and has the corresponding exponent to match):
1.0529513970757941370610747782095090628278032322332406685248932058897487219070703960159412040312324958550178793587321231496166104341706794282781804465303264220467370978600946532498508432543965246414865877765268438334467392843186701182578047022952222095279213542847547625013806063593981326312438954782159919569806945780558159983139494516214892022781358701106426838049878064090625594920050022451240382009550462442380576658723954500997837640072880232154236046343680085877727078528072722123195366215111990411019537148197442558048635218274092172396907226681705608220792266895576870551894550762902880978557369092132249954500903556336262479360506670537902070512869428970881638135729845035256195565406246915590828484638991615219052004055944813329481598847969387027700161783333580357966554786123158354267457962223811465954330911610564228730020236245605524128583533967685249775398427450933606825973311143113749366383842644503177277545696627287282123055942162951336932925420375112836461462120338241148915081655517081206432234061188196029609231357524022063469959597949051896076865883172740955991670305216873490456538967283758977304086971554554058064166260468764067261026647814993777560662012132796935609524129908146753623680552693333706194072338489699818137150849777160489153948872988676360548263714707910434915092735830288717124858521856367588043212890625e-578
Besides the much cleaner syntax of the C++ programs, the underlying GMP functions — “*_init”, “*_clear”, “*_mul”, etc. — are hidden in the C++ classes.
For Further Information
This article is my distillation of the MPIR readme file for a specific build scenario — please refer to \mpir-1.3.1\build.vc9\readme.txt for details on other builds.
Acknowledgement
Thanks to Brian Gladman for answering my questions and for suggesting I explore the C++ interface.
Works. Thanks.
The only problem is with step 5 and
“In the “Runtime Library” pulldown menu, select “Multi-threaded (/MT)”
Selecting this led to several error messages when building, so I let this as was and have this warning. Not a problem.
Thanks for help.
Hi megli,
I assume you are using an existing project? I guess the project depends on its existing setting for this. In any case, if the warning caused you no problem, then I guess all is well!
Thanks for letting me know.
I followed this instruction and when I wrote miniprogram which init and clear mpz_t variable compiler said:
1>—— Build started: Project: proba3, Configuration: Debug Win32 ——
1>Compiling…
1>main.cpp
1>Linking…
1>main.obj : error LNK2019: unresolved external symbol ___gmpz_clear referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol ___gmpz_init referenced in function _main
1>C:\Documents and Settings\Михаил\Мои документы\Visual Studio 2008\Projects\proba3\Debug\proba3.exe : fatal error LNK1120: 2 unresolved externals
1>Build log was saved at “file://c:\Documents and Settings\Михаил\Мои документы\Visual Studio 2008\Projects\proba3\proba3\Debug\BuildLog.htm”
1>proba3 – 3 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Can you help me?
mikhail,
It sounds like you missed a step: either you didn’t copy mpir.lib (and mpir.pdb) to the right place (step 4) or you forgot to add mpir.lib to your linker command line (step 5).
Hi again,
I am refering to step 5 and:
“In the “Runtime Library” pulldown menu, select “Multi-threaded (/MT)”
If you are using Debug configuration set this to “Multi-threaded Debug (/MTd)”
Otherwise it can build but at some point of writing your project you may get errors(in my case after including and overloading << operator)
So, for me, with Debug configuration it doesn't work with default setting or /MT but it works with /MTd.
That seems logical.
megli,
My instructions say to use “Multi-threaded (/MT)” because lib_mpir_p4 is built that way if you set it to “Release” in step 3. Are you using the debug configuration in the MPIR build? Then yes, “Multi-threaded Debug (/MTd)” is the right choice.
Thanks for the feedback.
Sounds like I missed step 4 or 5 but I didnt miss. I dont understand what wrong. And sometimes project mpir cant build 🙂
May be its important: I have AMD64 and build lib_mpir_k8. Then from folder “x64” copy mpir.lib and mpir.pdb to “visual studio 2008\VC\lib” , ….
mikhail,
Are you using Visual Studio 2008 instead of Visual Studio Express 2008 (that would be the only way you could build lib_mpir_k8 — it’s a 64-bit project)? In any case, I think you should be copying from /lib_mpir_k8 and not /x64.
Hi Mikhail,
According to your output, you are trying to build the debug configuaration for win32 but Rick’s description applies to win32 and release. When you build MPIR for debug use you need to select ‘win32’ and ‘debug’ in the configuaration manager and then select the multi-threaded debug library in the compiler property dialogue.
As Rick says, if you are using a win32 application you should not use the lib_mpir_k8 since this is an x64 library. The lib_mpir_p4 library should work on an AMD64 system operating in win32 mode.
Thx for help.
I built lim_mpir_p4 and now my mpir programms work sometimes. Namely when a changing properties of project. I think it is effect of my old broken windows or VC or smth like that.
When I said what I copy from “x64” I meant “lib_mpir_k8\x64\Release”.
Thank Rick, Brian very much!
I have finally installed it correctly. I thank you so much. You helped me a lot 🙂
Goodfellow — glad I could help!
Great article. Its about time 🙂
One quick question, using a .NET console app I can successfully use the C lib, but it will not compile if I use the c++ interface.
Both, compile and run fine using win32.
It seems there is a conflict with certain function in System namespace already defined: eg.
“public: __thiscall std::_Lockit::_Lockit(int)” (??0_Lockit@std@@QAE@H@Z) already defined in msvcprtd.lib(MSVCP90D.dll)
Any suggestions?
PS (take it easy on me, I am not a C++ or C programmer at all) However, the current libgmp wrapper I use in C#/VB is way to slow because of the unmanaged interop.
Alexander,
I’m afraid I can’t help you with .NET — sorry. (It’s particularly interesting that it works with the C and not C++ library — I’d expect both to work or fail, depending on how you built MPIR.)
A-HA!!!
You did miss a step, which goes between your step 2 and 3. Before you build your platform-specific project, you first have to build project GEN-MPIR. This project generates the header files that are required to build the platform-specific projects.
Dead Hand,
You shouldn’t need to build project gen-mpir manually — if you perform step 3, sub step 3 exactly as I’ve shown, it will be done automatically. (Which project are you building BTW?)
Thanks! This is exactly what I need and it works!
Hi,
what you described works, but do you know, how I can convert a mpz to a normal string?
I need it for example to set the text of a label.
Can you help??
Hi Chris,
The function “mpz_get_str()” is probably what you are looking for (see the GMP documentation I linked to above for details).
Well, I saw the function “mpz_get_str()” in the documantation before, but it returns a char.
I don’t know how to use or convert the function to get a normal string.
For example I want to set the text of a label:
Form1->labelsum->Text = ???
What do I have to write to convert a mpz to a string I can use to set the text?
Thanks for your answer, Chris
Chris,
mpz_get_str does return a string — this is from the documentation:
For example:
In my example, I printed the string, but you can assign it to your “label” field.
Hi,
thanks for the fast answer … you really helped me.
The problem was to convert a Standard C++ Library String () (which I get from the function) to a System::String of the .NET Framework (which I have to use for the text of the label).
I had to write:
std::string str = myString;
this->label1->Text = gcnew String(str.c_str());
and could not only write :
this->label1->Text = myString
Now it works perfectly.
Thanks
Chris,
I’m glad you solved your problem.
Since you’re using C++, you could also use the C++ interface to mpz_get_str — something like this:
std::string myString;
mpz_t myInt;
…
myString = myInt.get_str();
Now I know how to get a string from a mpz.
Can you give me a short example how to get one from a mpf.
I know that I have to use the function
mpf_get_str(char *str, mp exp t *expptr, int base, size t n_digits, mpf t op),
but I don’t know which parameters I have to pass and how (mainly I don’t know what is meant with mp_exp_t and n_digits).
I would be very happy when you could give me a short example like you did with the mpf. This was very helpful.
Chris,
The string returned by mpf_get_str() is just the digits after the radix point (not including leading 0s). n_digits specifies how many digits you want. *expptr is an output variable that contains the exponent — it tells you where to place the radix point.
For example, say you have a variable myFloat and you set it to 0.00123456789012. If you call mpf_get_str() with n_digits = 6, the returned string will be “123457”, and the exponent will be -2. This means the string should really be “0.0123457”, but you’ll have to write code to format it that way yourself.
When I write the following:
mpf_t myFloat;
mpf_init2(myFloat,10);
mpf_sqrt_ui (myFloat, 2); //Wurzel aus 2 berechnen
char str[10];
mp_exp_t * expptr; //I think this isn’t correct
mpf_get_str(str, expptr , 10, 10, myFloat);
I get a “System.AccessViolationException”.
I think I don’t use expptr correctly.
Can you say me, what I make false?
And how can I convert variable from the type mp_exp_t to an integer?
Chris,
I think the questions you are asking are more C related than GMP related. In any case, do this instead:
mp_exp_t exponent;
…
mpf_get_str(str, &exponent, 10, 10, myFloat);
Thank you very much.
Now I have no problems any more.
I followed the directions exactly and linked to mpir.lib and mpirxx.lib (this is C++ I’m using) and I tried the example program for floating point numbers for C++, but I get these errors:
error LNK2001: unresolved external symbol ___gmpz_set_si
error LNK2001: unresolved external symbol ___gmpz_mul
error LNK2001: unresolved external symbol ___gmpz_init
error LNK2001: unresolved external symbol ___gmpz_clear
error LNK2001: unresolved external symbol “class std::basic_ostream<char,struct std::char_traits > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits > &,struct __mpz_struct const *)” (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@PBU__mpz_struct@@@Z)
error LNK1120: 5 unresolved externals
I followed the directions exactly as to the placement of mpir.lib, mpir.pdb, mpirxx.lib, and mpirxx.pdb. Could you help please?
Hi Dave,
If you followed the instructions exactly I don’t know what could have gone wrong. The best I can suggest is to go through it one more time, checking that everything is the same. You might also want to read through the other users’ comments and see if anything there applies to you.
Please let us know if you figure it out.
Thanks for the quick reply Rick.
I followed the directions again, and when I built lib_mpir_cxx, in the Win32 directory it made mpir.lib and mpircxx.lib (not mpirxx.lib) so I followed the directions with those two, and it finally worked. Thanks for this page, I hate it how all the programming libraries are for linux and nobody thinks to make one for windows.
Interesting. Mine is definitely mpirxx.lib. I wrote these instructions using MPIR version 1.3.1 — perhaps you’re using a different version? In any case, I’m glad it worked out.
Oh, no wonder then, I grabbed the latest version off t he MPIR website, which is 2.1.1.
I have folloewd the steps and then built your c++ example of mpz_class.
after I built it I tried to activate the exe file but I get an error “activiation failed beacuse mpir.dll wasn’t found”. what’s the problem ?
napr,
Are you sure you followed the directions exactly? They are for building a static library, not a dynamic one.
Great article, it helps me so much.
Thanks, this helped 🙂
For those having problems, if you built a 64 bit version, you might need to set it to release and x64 before it starts working, debug does not work for me. (1 error C2059 and 20 errors C2018) If someone else knows why, I’d be delighted to know.
Your debug build probably didn’t work because it was being linked with the wrong run-time library. You need to ensure that your application uses the same run-time library as that used when MPIR is built. The other possible issue is when a build is done without cleaning out an earlier build – this should be automatic but I have found that this sometimes fails.
Brian
Thanks for the help! It worked!
I have 2 questions for you:
1. Which project should I build? I have a Intel T2300 Core 2 CPU. It is Pentium M.
2. I set the /MT switch, but it did not compile. So I changed to /MD and that worked. However, it still has LNK4098 warning. How do you get rid of it?
Thanks!
B7,
I haven’t tried MPIR on a 64-bit CPU, but you can try lib_mpir_core2 (and maybe /MT will work OK with it).
Hi,
Sorry for the delay but I don’t visit Rick’s site all that regularly.
If you are running a 64-bit Windows system, you need the lib_mpir_core2 built for x64 and release. This uses /MT as the default so it should work.
If you have issues with MPIR you will get a more rapid response if you use an MPIR forum such as:
http://groups.google.com/group/mpir-devel
Brian Gladman
Thanks Brian. (What, you don’t visit my site “regularly”? I’m outraged :).)
Thanks for article.
It is very useful, but i have one problem. I did all steps, which needed for install this library. When i compile 1-st, 2-d and 3-d example, i do not have errors. When i compile last example arrive 10 errors:
1>Compiling…
1>main.cpp
1>Linking…
1>msvcprtd.lib(MSVCP90D.dll) : error LNK2005: “public: class std::locale::facet * __thiscall std::locale::facet::_Decref(void)” (?_Decref@facet@locale@std@@QAEPAV123@XZ) already defined in mpirxx.lib(osmpf.obj)
1>libcpmt.lib(locale0.obj) : error LNK2005: “void __cdecl _AtModuleExit(void (__cdecl*)(void))” (?_AtModuleExit@@YAXP6AXXZ@Z) already defined in msvcprtd.lib(locale0_implib.obj)
1>libcpmt.lib(locale0.obj) : error LNK2005: “private: static class std::locale::_Locimp * __cdecl std::locale::_Getgloballocale(void)” (?_Getgloballocale@locale@std@@CAPAV_Locimp@12@XZ) already defined in msvcprtd.lib(MSVCP90D.dll)
1>libcpmt.lib(locale0.obj) : error LNK2005: __Fac_tidy already defined in msvcprtd.lib(locale0_implib.obj)
1>libcpmt.lib(locale0.obj) : error LNK2005: “private: static void __cdecl std::locale::facet::facet_Register(class std::locale::facet *)” (?facet_Register@facet@locale@std@@CAXPAV123@@Z) already defined in msvcprtd.lib(locale0_implib.obj)
1>libcpmt.lib(locale0.obj) : error LNK2005: “public: static void __cdecl std::_Locinfo::_Locinfo_dtor(class std::_Locinfo *)” (?_Locinfo_dtor@_Locinfo@std@@SAXPAV12@@Z) already defined in msvcprtd.lib(MSVCP90D.dll)
1>libcpmt.lib(locale0.obj) : error LNK2005: “public: static void __cdecl std::_Locinfo::_Locinfo_ctor(class std::_Locinfo *,class std::basic_string<char,struct std::char_traits,class std::allocator > const &)” (?_Locinfo_ctor@_Locinfo@std@@SAXPAV12@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z) already defined in msvcprtd.lib(MSVCP90D.dll)
1>libcpmt.lib(xlock.obj) : error LNK2005: “public: __thiscall std::_Lockit::_Lockit(int)” (??0_Lockit@std@@QAE@H@Z) already defined in msvcprtd.lib(MSVCP90D.dll)
1>libcpmt.lib(xlock.obj) : error LNK2005: “public: __thiscall std::_Lockit::~_Lockit(void)” (??1_Lockit@std@@QAE@XZ) already defined in msvcprtd.lib(MSVCP90D.dll)
1>LINK : warning LNK4098: defaultlib ‘LIBCMT’ conflicts with use of other libs; use /NODEFAULTLIB:library
1>C:\Users\home\Documents\Visual Studio 2008\Projects\Test\Debug\Test.exe : fatal error LNK1169: one or more multiply defined symbols found
1>Build log was saved at “file://c:\Users\home\Documents\Visual Studio 2008\Projects\Test\Test\Debug\BuildLog.htm”
1>Test – 10 error(s), 1 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
When i delete this string program works correct.
cout << setprecision (1343) << aSmallPO2 << endl;
Could you help me?
@kusha,
Do you get the same error if you just delete the setprecision() part of that statement? In any case, I don’t know what is happening. Sorry.
How do I do this for Visual C++ 6 and mpir-2.4.0?
Or do I neet to get a specif version of MPIR for that??
@mahaju,
I haven’t tried that combo, but the MPIR readme suggests it won’t work:
Hi, I have the same problem as kusha. I tried several combinations of /NODEFAULTLIB:library with no result.
When I change “cout << setprecision (1343) << aSmallPO2 << endl;" to "cout << setprecision (1343) << endl;" the project links ok.
Thanks a lot for any help.
@Daniel,
I don’t know if (or how) kusha resolved his problem. Maybe if you tell us more about your system and the versions you installed (if different from above) someone can help you.
Hi Rick Regan,
First of all, thanks for such a great article. However, I ran into the same problem that Dave encountered. For C version, everything works well. But for C++, I got many `unresolved symbols` problems. Have you tried to build the latest version of MPIR (2.40) in VC++2010? I personally think there are several problems to C++ version of MPIR with VC++2010 specially. Let me know if you can build it successfully. Thank you.
@Chan,
I am still using exactly the setup I describe in this article (MPIR 1.3.1, Visual Studio 2008, etc.) (If it ain’t broke, don’t fix it 🙂 .) If I ever upgrade I’ll be sure to update my instructions. In the meantime, maybe you can find some help at mpir.org. Thanks and good luck.
@Rick Regan: Thanks again for your quick response. It’s kinda odd when the build process failed only on C++. But I really don’t know how were you be able to use the same “exact” set up though. Because the mpir-2.40 that I downloaded doesn’t have the “\mpir-1.3.1\build.vc9\yasm.rules” but “vsyasm.props, vsyasm.targets, and vsyasm.xml”. Anyhow, I’m look forward to seeing your new tutorial on a newer version MPIR 2.40 ;). And of-course thanks for the link to further help.
@Chan,
I haven’t rebuilt since I wrote this article (March 2010), so I am in fact using the versions of everything as listed.
@Rick: Would you mind rebuilding the 2.4.0 version to help me address this issue? Thanks in advance 😉
@Chan,
Perhaps you can get help at the mpir-devel group. Please let us know if you resolve your issue.
Regarding @Chan’s problem: he was building the 32-bit library for a 64-bit system (see his question on stackoverflow.)
Trying to compile mpir-3.0.0 using the tutorial here but there isn’t \build.vc10\yasm.rules
What should I do?
@boredchimp,
I’m still using my old build of MPIR — perhaps you can get help at the mpir-devel group? Sorry.
This is a comment I received by email from Anil Philip:
For those wanting to build a newer version of mpir, just go to mpir-2.5.1\win and run the two batch files in a command window. You will need to download yasm, rename and copy over yasm.exe to C:\Program Files\Microsoft Visual Studio 9.0\VC\bin.
Nice job Rick ! thanks a lot, It is very helpful
Hi, one question, would you mind telling me how to install everything but for visual 2010?.
Thanks
@Roberto,
Sorry, I have not upgraded to VS 2010 yet.
Thank you for your tutorial, I followed it and after some struggle I managed to work out your c++ example. However when I try to run this code:
mpq_class x(1), y(1), z(1), a(93, 10), b(98, 10);
for (int i = 0; i < 15; i++)
{
x *= a;
y *= b;
z *= (a * b);
}
//works good so far
//std::cout << z << "\n" << (x*y) << std::endl;
//gives error:
Error 26 error LNK1169: one or more multiply defined symbols found
Error 13 error LNK2005: "public: __int64 __thiscall std::basic_streambuf<char,struct std::char_traits >::sputn(char const *,__int64)” (?sputn@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QAE_JPBD_J@Z) already defined in mpirxx.lib(osdoprnti.obj)
and some more errors. This works when I write the following though:
cout << z.get_d() << endl;
However, I want to be able to display the numbers in a ratio format. Any ideas?
By the way, I am using 64 bit Visual Studio 2010. But I built it in Win32, and your example works fine.
Ahmet,
Sorry, I have not tried it on 64-bit.
Thank you for the tutorial. All your examples work for me, except last line in floating point c++ interface: cout << setprecision (1343) << aSmallPO2 << endl; Even without setprecision is not building. I download mpir-2.2.1 as the last version supporting VS2008, and build lib_mpir_gc instead lib_mpir_p4. I build in release mode – 32bit version on XP. The error is same as kusha reported above. Do you know how to resolve this problem?
@Dejan,
Sorry, I’m still on my original build, even on my 64-bit machine.
On step 4, files mpir.lib and mpir.pdb from mpir version 2.6 aren’t present, searched the entire directory tree, can get everything else to work though.
never mind, figured it out, thanks
the file is not yasm-0.8.0-win32.exe
@Geisi,
I don’t know what you mean. The link in my article points to yasm-0.8.0-win32.exe.
Thanks alot!
If you’re trying to build and it fails, try downloading yasm from here http://yasm.tortall.net/Download.html and download vsyasm, not yasm! It worked for me.
Also check out the readme.txt at build.vc10, it might help.
What is a licence of your code ? ( I would like to put it in wikiboks , like here :
https://pl.wikibooks.org/wiki/Programowanie_w_systemie_UNIX/GMP
With info/link to your page )
@Adam,
It’d be best if you just linked to my site instead of copying the code. It’s not that I want to protect the code per se, but my articles are copyrighted. I appreciate the interest though. Thanks for asking.
Any chance of updating this for Visual Studio 10 and vsyasm @ http://yasm.tortall.net/Download.html .
I had no luck trying following your instructions with these (mpir.lib just isn’tt there).
Thanks.
William Boyd
@William,
Sorry, I still use this old setup. I don’t know how to set it up with the new releases.
lib_mpir_p4 built is failed
giving error
yasm’ is not recognized as an internal or external command,
6>operable program or batch file.
6>Project : error PRJ0019: A tool returned an error code from “Assembling submul_1.asm”
@Anny
It is likely that you have not installed vsyasm.exe as set out in the readme.txt file in the Visual Studio build directory of the MPIR distribution. I am the Windows developer of MPIR and will be happy to give any advice you need in getting this to work. However if you have further questions, you are likely to get a faster answer if you ask on the MPIR developer list at mpir-devel@googlegroups.com
best regards,
Brian Gladman
I did all that you suggested but when I went to install
1.Open the MPIR Visual C++ solution \mpir-1.3.1\build.vc9\mpir.sln.
it brought up visual c++ but required updates for all and you couldn’t ignore that. each project had 2 errors and when it was done the solution had 0 projects rather than 14.
what am I doing wrong?
thank you
david
@David,
I’m sorry that I can’t help you (these build instructions are over four years old and I haven’t built a new version). Maybe you should try mpir-devel@googlegroups.com as indicated in comment #79 above.
I’m trying to get this to work for mpir-2.6.0 on MsVC 2013 Express. The build works (I chose lib_mpir_gc). I copied mpir.lib and mpir.pdb from “mpir-2.6.0\build.vc10\Win32\Release” to “C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\lib”, and mpir.h from “mpir-2.6.0\lib\Win32\Release” or “mpir-2.6.0” (the two copies are identical) to “C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include”. When I try to build the first test program above (prints out 2^1920) in a new (empty) project, I get this error message:
error C1083: Cannot open source file: ‘mpir.lib’: No such file or directory
Any ideas?
Forgot to say, for the new empty project:
…followed step 5. – project “Properties” > “Configuration Properties” > “Linker” > “Command Line” > “Additional options” :- mpir.lib.
Also did this project “Properties” > “Configuration Properties” > “C/C++” > “Code Generation” > “Runtime Library” :- “Multi-threaded (/MT)”.
@Robert,
Sorry, I have not tried the build on newer versions. Perhaps try the MPIR Google group (see comments above).
I followed your steps. It all gone well. I successfully Built the project. But when I run the program it said that …
“The program can’t start because mpir.dll is missing from your computer”
(This article refers to old versions and is thus out-of-date — I have closed comments.)