简体   繁体   中英

How do I define an array in C++ that holds GMP variables?

How do I create an array in C++ that holds mpz variables?

I am trying to use:

int array_size = 5;
mpz_t numerator_arr;
for (i = 0; i < array_size; i++) {
    mpz_init2(numerator_arr[i], 100);
}
numerator_arr = { 1, -1, 1, 5, -691 };

but this returns the error:

test.cpp: In function ‘int main()’:
test.cpp:13:34: error: cannot convert ‘__mpz_struct’ to ‘mpz_ptr {aka __mpz_struct*}’ for argument ‘1’ to ‘void __gmpz_init2(mpz_ptr, mp_bitcnt_t)’
   mpz_init2(numerator_arr[i], 100);
                                  ^
test.cpp:17:38: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11 [enabled by default]
  numerator_arr = { 1, -1, 1, 5, -691 };
                                      ^
test.cpp:17:16: error: assigning to an array from an initializer list
  numerator_arr = { 1, -1, 1, 5, -691 };
                ^

EDIT**: After some more digging, I found that I need to declare my array with

mpz_t *numerator_arr = new mpz_t[array_size];

but the compiler is still returning the errors:

test.cpp:17:38: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11 [enabled by default]
  numerator_arr = { 1, -1, 1, 5, -691 };
                                      ^
test.cpp:17:16: error: cannot convert ‘<brace-enclosed initializer list>’ to ‘__mpz_struct (*)[1]’ in assignment
  numerator_arr = { 1, -1, 1, 5, -691 };
                ^

When I try to use

vector<mpz_class> numerator_arr{ 1, -1, 1, -1, 5, -691, 7 };

it gives me the errors:

test.cpp:12:60: error: in C++98 ‘numerator_arr’ must be initialized by constructor, not by ‘{...}’
  vector<mpz_class> numerator_arr{ 1, -1, 1, -1, 5, -691, 7 };
                                                            ^
test.cpp:12:60: error: no matching function for call to ‘std::vector<__gmp_expr<__mpz_struct [1], __mpz_struct [1]> >::vector(<brace-enclosed initializer list>)’
test.cpp:12:60: note: candidates are:
In file included from /usr/lib/gcc/x86_64-pc-cygwin/4.8.3/include/c++/vector:64:0,
                 from test.cpp:2:
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/include/c++/bits/stl_vector.h:398:9: note: template<class _InputIterator> std::vector<_Tp, _Alloc>::vector(_InputIterator, _InputIterator, const allocator_type&)
         vector(_InputIterator __first, _InputIterator __last,
         ^
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/include/c++/bits/stl_vector.h:398:9: note:   template argument deduction/substitution failed:
test.cpp:12:60: note:   cannot convert ‘1’ (type ‘int’) to type ‘const allocator_type& {aka const std::allocator<__gmp_expr<__mpz_struct [1], __mpz_struct [1]> >&}’
  vector<mpz_class> numerator_arr{ 1, -1, 1, -1, 5, -691, 7 };
                                                            ^

When I try to use

mpz_class numerator_arr[] = { 1, -1, 1, -1 }

and I try to store numbers like

-94598037819122125295227433069493721872702841533066936133385696204311395415197247711

the compiler returns these warnings and errors:

test.cpp:29:3: warning: this decimal constant is unsigned only in ISO C90 [enabled by default]
test.cpp:30:4: warning: integer constant is too large for its type [enabled by default]
   -94598037819122125295227433069493721872702841533066936133385696204311395415197247711 };
    ^
test.cpp: In function ‘int main()’:
test.cpp:30:88: error: conversion from ‘__int128 unsigned’ to ‘mpz_class {aka __gmp_expr<__mpz_struct [1], __mpz_struct [1]>}’ is ambiguous
   -94598037819122125295227433069493721872702841533066936133385696204311395415197247711 };
                                                                                        ^
test.cpp:30:88: note: candidates are:
In file included from test.cpp:2:0:
/usr/include/gmpxx.h:1423:3: note: __gmp_expr<__mpz_struct [1], __mpz_struct [1]>::__gmp_expr(double)
   __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
   ^
/usr/include/gmpxx.h:1423:3: note: __gmp_expr<__mpz_struct [1], __mpz_struct [1]>::__gmp_expr(float)
   __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
   ^
/usr/include/gmpxx.h:1423:3: note: __gmp_expr<__mpz_struct [1], __mpz_struct [1]>::__gmp_expr(long unsigned int)
   __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
   ^
/usr/include/gmpxx.h:1423:3: note: __gmp_expr<__mpz_struct [1], __mpz_struct [1]>::__gmp_expr(long int)
   __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
   ^
/usr/include/gmpxx.h:1423:3: note: __gmp_expr<__mpz_struct [1], __mpz_struct [1]>::__gmp_expr(short unsigned int)
   __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
   ^
/usr/include/gmpxx.h:1423:3: note: __gmp_expr<__mpz_struct [1], __mpz_struct [1]>::__gmp_expr(short int)
   __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
   ^
/usr/include/gmpxx.h:1423:3: note: __gmp_expr<__mpz_struct [1], __mpz_struct [1]>::__gmp_expr(unsigned int)
   __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
   ^
/usr/include/gmpxx.h:1423:3: note: __gmp_expr<__mpz_struct [1], __mpz_struct [1]>::__gmp_expr(int)
   __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
   ^
/usr/include/gmpxx.h:1423:3: note: __gmp_expr<__mpz_struct [1], __mpz_struct [1]>::__gmp_expr(unsigned char)
   __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
   ^
/usr/include/gmpxx.h:1423:3: note: __gmp_expr<__mpz_struct [1], __mpz_struct [1]>::__gmp_expr(signed char)
   __GMPXX_DEFINE_ARITHMETIC_CONSTRUCTORS
   ^

This is my first time working with arrays in GMP. Any help would be greatly appreciated.

Well, summing up all the comments above, if you are dealing with a lot of array modification in your code(insertion/remove) it is best to use vector<mpz_class> to hold your mpz_class variables. And the reason that it is better for you to use mpz_class instead of mpz_t is first you don't have to worry about keeping track with memory you use for the variables( mpz_init()/mpz_clear() ) and second the code you write becomes much clearer as many of operators are mapped with mpz_class

Regarding the errors, your vector<mpz_class> code is resulting error because you are not correctly instantiating the variables. May be what you meant was

mpz_class numerator_arr[] = { 1, -1, 1, -1 };
vector<mpz_class> arr (numerator_arr);

And when you tried to store huge numbers into a mpz_class you are getting an error because the when you initialize the mpz_class with like this:

mpz_class m(-11111111111111111111111111111111111111111111111)

you are already initializing huge number into the primitive int type. And in your case the number is assigned as an unsigned 16 byte int because it is just too large and gmp does not provide any constructor to make it into its mpz_class structure. You will be better of making the input argument as string(const char*) rather than an int. So it will be

mpz_class m("-11111111111111111111111111111111111111111111111")

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM