0

I am building a C++ program to verify a mathematical conjecture for up to 100 billion iterations. In order to test such high numbers, I cannot use a C++ int, so I am using the NTL library, using the type ZZ as my number type.

My algorithm looks like this:

ZZ generateNthSeq(ZZ n)
{
    return floor(n*sqrt(2));
}

I have the two libraries being imported:

#include <cmath>
#include <NTL/ZZ.h>

But obviously this cannot compile because I get the error:

$ g++ deepness*.cpp
deepness.cpp: In function ‘NTL::ZZ generateNthSeq(NTL::ZZ)’:
deepness.cpp:41: error: no matching function for call to ‘floor(NTL::ZZ)’
/usr/include/bits/mathcalls.h:185: note: candidates are: double floor(double)
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/cmath:262: note:                 long double std::floor(long double)
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/cmath:258: note:                 float std::floor(float)

Stating that the floor mathematical operation cannot accept a ZZ class type. But I need the numbers to be pretty big. How can I accomplish what I want to do, which is to floor the function, while using the NTL library?

CtheGood
  • 999
  • 8
  • 17
  • Looks like n * squrt(2) is returning a double instead of an NTL::ZZ Maybe your library has its own squrt function? – KABoissonneault May 27 '15 at 16:54
  • 2
    I don't know the library, but if it is the one described at http://www.shoup.net/ntl/doc/tour-ex1.html apparently it has "`SqrRoot` -- integer part of square root". So you could try something like `SqrRoot(2*n*n)`, assuming n is positive (and `-SqrRoot(2*n*n)` otherwise). – CompuChip May 27 '15 at 16:55
  • Thanks guys. I have changed my algorithm to have `floor(SqrRoot(2*n*n))`. The `SqrRoot` now returns a ZZ, but still there is not `floor` function in the NTL library or C++ libraries that accepts a `ZZ`, which is the real problem listed above. There is no matching call for a `floor:(NTL::ZZ)`. Need more help. – CtheGood May 27 '15 at 17:00
  • 2
    Why do you need to apply floor? According to what I quoted, SqrRoot already returns the _integer part_ of the square root. – CompuChip May 27 '15 at 17:02
  • .. specifically, the header comments `x = floor(a^{1/2}) (a >= 0)` –  May 27 '15 at 17:02
  • Sorry @CompuChip, I missed where you talked about the integer part of the square root. I looked that up and you are correct. I'm applying those changes right now. Thanks - I'll report if it worked or not. – CtheGood May 27 '15 at 17:05
  • @CompuChip your answer was most helpful. I was able to get those changes in, and it worked like a charm. Thanks for looking that up for me. Wish I could give you more points then just an upped comment. – CtheGood May 28 '15 at 02:29

1 Answers1

4

Note that it doesn't really make sense to apply floor to an integral type (well, it does, it's just a no-op). What you should be really worried about is the fact that your code is apparently passing something of type ZZ into floor!

That is, what can n * sqrt(2) possibly mean here?

Also, before even writing that, I'd've checked the documentation to see if integer * floating point actually exists in the library -- usually for that to be useful at all, you need arbitrary precision floating types available.


Checking through the headers, there is only one multiplication operator:

ZZ operator*(const ZZ& a, const ZZ& b);

and there is a conversion constructor:

explicit ZZ(long a);  // promotion constructor

I can't figure out how your code is even compiling. Maybe you're using a different version of the library than I'm looking at, and the conversion constructor is implicit, and your double is getting "promoted" to a ZZ. This is surely not what you want, since promoting sqrt(2) to a ZZ is simply going to give you the integer 1.

You either need to:

  • look into whether or not NTL has arbitrary precision floating point capabilities
  • switch to a library that does have arbitrary precision floating point capabilities
  • convert your calculation to pure integer arithmetic

That last one is fairly easy here: you want

return SqrRoot(sqr(n) * 2); // sqr(n) will be a bit more efficient than `n * n`
  • 1
    Incidentally, even if you had arbitrary precision floating point available, the pure integer version is still probably the better way to do the calculation. –  May 27 '15 at 17:07
  • Thanks @Hurkyl for all your information. The thing I really needed was just the last bit you mentioned. This is for a class, and there are requirements for libraries to be used and how to set this up, so I was under the constraints I mentioned above. What I really needed to know was the SqrRoot() NTL function returned an rounded off int, which was what I needed. – CtheGood May 28 '15 at 02:28