From c1f1e35236548aca9ab71ac191d8ac4d80631f66 Mon Sep 17 00:00:00 2001 From: Markus Blatt <mblatt@dune-project.org> Date: Fri, 18 Sep 2009 13:44:46 +0000 Subject: [PATCH] Do not assume the sizes of integral types. Just ask numeric_limits. Otherwise on some 64bit platforms we run into trouble. [[Imported from SVN: r5576]] --- common/bigunsignedint.hh | 52 ++++++++++++++++++------------- common/test/bigunsignedinttest.cc | 22 +++++++++++++ 2 files changed, 52 insertions(+), 22 deletions(-) diff --git a/common/bigunsignedint.hh b/common/bigunsignedint.hh index cf2cc74d5..6f56fb236 100644 --- a/common/bigunsignedint.hh +++ b/common/bigunsignedint.hh @@ -47,7 +47,8 @@ namespace Dune public: // unsigned short is 16 bits wide, n is the number of digits needed - enum { n=k/16+(k%16!=0), bits=16, hexdigits=4, bitmask=0xFFFF, compbitmask=0xFFFF0000, + enum { bits=std::numeric_limits<unsigned short>::digits, n=k/bits+(k%bits!=0), + hexdigits=4, bitmask=0xFFFF, compbitmask=0xFFFF0000, overflowmask=0x1 }; //! Construct uninitialized @@ -57,7 +58,7 @@ namespace Dune bigunsignedint (int x); //! Construct from unsigned int - bigunsignedint (unsigned int x); + bigunsignedint (std::size_t x); //! Print number in hex notation void print (std::ostream& s) const ; @@ -132,6 +133,8 @@ namespace Dune #if HAVE_MPI friend class MPITraits<bigunsignedint<k> >; #endif + inline void assign(std::size_t x); + } ; @@ -143,20 +146,25 @@ namespace Dune template<int k> bigunsignedint<k>::bigunsignedint (int y) { - unsigned int x = std::abs(y); - // assume unsigned int is 32 bits - digit[0] = (x&bitmask); - if (n>1) digit[1] = (x>>bits)&bitmask; - for (unsigned int i=2; i<n; i++) digit[i]=0; + std::size_t x = std::abs(y); + assign(y); } template<int k> - bigunsignedint<k>::bigunsignedint (unsigned int x) + bigunsignedint<k>::bigunsignedint (std::size_t x) + { + assign(x); + } + template<int k> + void bigunsignedint<k>::assign(std::size_t x) { - // assume unsigned int is 32 bits - digit[0] = (x&bitmask); - if (n>1) digit[1] = (x>>bits)&bitmask; - for (unsigned int i=2; i<n; i++) digit[i]=0; + int no=std::numeric_limits<std::size_t>::digits/bits; + + for(int i=0; i<no; ++i) { + digit[i] = (x&bitmask); + x=x>>bits; + } + for (unsigned int i=no; i<n; i++) digit[i]=0; } // export @@ -438,70 +446,70 @@ namespace Dune template <int k> - inline bigunsignedint<k> operator+ (const bigunsignedint<k>& x, unsigned int y) + inline bigunsignedint<k> operator+ (const bigunsignedint<k>& x, std::size_t y) { bigunsignedint<k> temp(y); return x+temp; } template <int k> - inline bigunsignedint<k> operator- (const bigunsignedint<k>& x, unsigned int y) + inline bigunsignedint<k> operator- (const bigunsignedint<k>& x, std::size_t y) { bigunsignedint<k> temp(y); return x-temp; } template <int k> - inline bigunsignedint<k> operator* (const bigunsignedint<k>& x, unsigned int y) + inline bigunsignedint<k> operator* (const bigunsignedint<k>& x, std::size_t y) { bigunsignedint<k> temp(y); return x*temp; } template <int k> - inline bigunsignedint<k> operator/ (const bigunsignedint<k>& x, unsigned int y) + inline bigunsignedint<k> operator/ (const bigunsignedint<k>& x, std::size_t y) { bigunsignedint<k> temp(y); return x/temp; } template <int k> - inline bigunsignedint<k> operator% (const bigunsignedint<k>& x, unsigned int y) + inline bigunsignedint<k> operator% (const bigunsignedint<k>& x, std::size_t y) { bigunsignedint<k> temp(y); return x%temp; } template <int k> - inline bigunsignedint<k> operator+ (unsigned int x, const bigunsignedint<k>& y) + inline bigunsignedint<k> operator+ (std::size_t x, const bigunsignedint<k>& y) { bigunsignedint<k> temp(x); return temp+y; } template <int k> - inline bigunsignedint<k> operator- (unsigned int x, const bigunsignedint<k>& y) + inline bigunsignedint<k> operator- (std::size_t x, const bigunsignedint<k>& y) { bigunsignedint<k> temp(x); return temp-y; } template <int k> - inline bigunsignedint<k> operator* (unsigned int x, const bigunsignedint<k>& y) + inline bigunsignedint<k> operator* (std::size_t x, const bigunsignedint<k>& y) { bigunsignedint<k> temp(x); return temp*y; } template <int k> - inline bigunsignedint<k> operator/ (unsigned int x, const bigunsignedint<k>& y) + inline bigunsignedint<k> operator/ (std::size_t x, const bigunsignedint<k>& y) { bigunsignedint<k> temp(x); return temp/y; } template <int k> - inline bigunsignedint<k> operator% (unsigned int x, const bigunsignedint<k>& y) + inline bigunsignedint<k> operator% (std::size_t x, const bigunsignedint<k>& y) { bigunsignedint<k> temp(x); return temp%y; diff --git a/common/test/bigunsignedinttest.cc b/common/test/bigunsignedinttest.cc index 607da28c9..2586185cb 100644 --- a/common/test/bigunsignedinttest.cc +++ b/common/test/bigunsignedinttest.cc @@ -47,8 +47,25 @@ int main() Dune::bigunsignedint<100> a, b, c; a=100; + int ret=0; + if(a.touint()!=100) + { + std::cerr<<"wrong conversion"<<std::endl; + ++ret; + } + b=3; + if(b.touint()!=3) + { + std::cerr<<"wrong conversion"<<std::endl; + ++ret; + } c=a/b; + if(c.touint()!=100/3) + { + std::cerr<<"wrong conversion"<<std::endl; + ++ret; + } std::cout<<a<<"/"<<b<<"="<<c<<std::endl; try{ @@ -57,8 +74,13 @@ int main() b=0; c=a/1; std::cout<<a1<<"/"<<b1<<"="<<c1<<std::endl; + return ret; + } catch(Dune::MathError e) { std::cout<<e<<std::endl; + return 1; } + + } -- GitLab