Commit 8c2e5f36 by Paolo Carlini Committed by Paolo Carlini

random.tcc (struct _To_Unsigned_Type): Add.

2006-07-14  Paolo Carlini  <pcarlini@suse.de>

	* include/tr1/random.tcc (struct _To_Unsigned_Type): Add.
	(subtract_with_carry<>::seed(_Gen&, false_type)): Use an
	unsigned type in the loop, fix factor multiplier, take g
	invocations modulo 2^32.

	* include/tr1/random.tcc (subtract_with_carry<>::
	seed(unsigned long)): Fix value == 0 special case.

	* include/tr1/random (struct _Shift): Fix for large shifts.

From-SVN: r115439
parent 4f543d15
2006-07-14 Paolo Carlini <pcarlini@suse.de>
* include/tr1/random.tcc (struct _To_Unsigned_Type): Add.
(subtract_with_carry<>::seed(_Gen&, false_type)): Use an
unsigned type in the loop, fix factor multiplier, take g
invocations modulo 2^32.
* include/tr1/random.tcc (subtract_with_carry<>::
seed(unsigned long)): Fix value == 0 special case.
* include/tr1/random (struct _Shift): Fix for large shifts.
2006-07-13 Paolo Carlini <pcarlini@suse.de> 2006-07-13 Paolo Carlini <pcarlini@suse.de>
* testsuite/performance/21_strings/string_copy_cons_and_dest.cc: New. * testsuite/performance/21_strings/string_copy_cons_and_dest.cc: New.
......
...@@ -125,7 +125,7 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) ...@@ -125,7 +125,7 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1)
} }
template<typename _UIntType, int __w, bool = template<typename _UIntType, int __w, bool =
__w != std::numeric_limits<_UIntType>::digits> __w < std::numeric_limits<_UIntType>::digits>
struct _Shift struct _Shift
{ static const _UIntType __value = 0; }; { static const _UIntType __value = 0; };
......
...@@ -102,6 +102,28 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) ...@@ -102,6 +102,28 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1)
2 + std::numeric_limits<_RealType>::digits * 3010/10000; 2 + std::numeric_limits<_RealType>::digits * 3010/10000;
}; };
template<typename _ValueT>
struct _To_Unsigned_Type
{ typedef _ValueT _Type; };
template<>
struct _To_Unsigned_Type<short>
{ typedef unsigned short _Type; };
template<>
struct _To_Unsigned_Type<int>
{ typedef unsigned int _Type; };
template<>
struct _To_Unsigned_Type<long>
{ typedef unsigned long _Type; };
#ifdef _GLIBCXX_USE_LONG_LONG
template<>
struct _To_Unsigned_Type<long long>
{ typedef unsigned long long _Type; };
#endif
} // namespace _Private } // namespace _Private
...@@ -347,6 +369,9 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) ...@@ -347,6 +369,9 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1)
subtract_with_carry<_IntType, __m, __s, __r>:: subtract_with_carry<_IntType, __m, __s, __r>::
seed(unsigned long __value) seed(unsigned long __value)
{ {
if (__value == 0)
__value = 19780503;
std::tr1::linear_congruential<unsigned long, 40014, 0, 2147483563> std::tr1::linear_congruential<unsigned long, 40014, 0, 2147483563>
__lcg(__value); __lcg(__value);
...@@ -357,35 +382,35 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1) ...@@ -357,35 +382,35 @@ _GLIBCXX_BEGIN_NAMESPACE(tr1)
_M_p = 0; _M_p = 0;
} }
//
// This implementation differs from the tr1 spec because the tr1 spec refused
// to make any sense to me: the exponent of the factor in the spec goes from
// 1 to (n-1), but it would only make sense to me if it went from 0 to (n-1).
//
// This algorithm is still problematic because it can overflow left right and
// center.
//
template<typename _IntType, _IntType __m, int __s, int __r> template<typename _IntType, _IntType __m, int __s, int __r>
template<class _Gen> template<class _Gen>
void void
subtract_with_carry<_IntType, __m, __s, __r>:: subtract_with_carry<_IntType, __m, __s, __r>::
seed(_Gen& __gen, false_type) seed(_Gen& __gen, false_type)
{ {
const int __n = (std::numeric_limits<_IntType>::digits + 31) / 32; const int __n = (std::numeric_limits<_IntType>::digits + 31) / 32;
for (int __i = 0; __i < long_lag; ++__i)
{ typedef typename _Private::_Select<(sizeof(unsigned) == 4),
_M_x[__i] = 0; unsigned, unsigned long>::_Type _UInt32Type;
unsigned long __factor = 1;
for (int __j = 0; __j < __n; ++__j) typedef typename _Private::_To_Unsigned_Type<_IntType>::_Type
{ _UIntType;
_M_x[__i] += __gen() * __factor;
__factor *= 0x80000000; for (int __i = 0; __i < long_lag; ++__i)
} {
_M_x[__i] = _Private::__mod<_IntType, 1, 0, modulus>(_M_x[__i]); _UIntType __tmp = 0;
} _UIntType __factor = 1;
_M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0; for (int __j = 0; __j < __n; ++__j)
_M_p = 0; {
} __tmp += (_Private::__mod<_UInt32Type, 1, 0, 0>(__gen())
* __factor);
__factor *= _Private::_Shift<_UIntType, 32>::__value;
}
_M_x[__i] = _Private::__mod<_UIntType, 1, 0, modulus>(__tmp);
}
_M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0;
_M_p = 0;
}
template<typename _IntType, _IntType __m, int __s, int __r> template<typename _IntType, _IntType __m, int __s, int __r>
typename subtract_with_carry<_IntType, __m, __s, __r>::result_type typename subtract_with_carry<_IntType, __m, __s, __r>::result_type
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment