зеркало из https://github.com/github/ruby.git
random.c: optimize int_pair_to_real_inclusive
* random.c (int_pair_to_real_inclusive): optimize to multiply without Bignum. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54938 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
091d88ab4b
Коммит
ed5b985650
|
@ -1,3 +1,8 @@
|
||||||
|
Sat May 7 16:22:13 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* random.c (int_pair_to_real_inclusive): optimize to multiply
|
||||||
|
without Bignum.
|
||||||
|
|
||||||
Sat May 7 07:58:02 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Sat May 7 07:58:02 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* process.c (rb_exec_getargs): honor the expected argument types
|
* process.c (rb_exec_getargs): honor the expected argument types
|
||||||
|
|
46
random.c
46
random.c
|
@ -279,41 +279,23 @@ rb_genrand_real(void)
|
||||||
static double
|
static double
|
||||||
int_pair_to_real_inclusive(uint32_t a, uint32_t b)
|
int_pair_to_real_inclusive(uint32_t a, uint32_t b)
|
||||||
{
|
{
|
||||||
VALUE x;
|
|
||||||
VALUE m;
|
|
||||||
uint32_t xary[2], mary[2];
|
|
||||||
double r;
|
double r;
|
||||||
|
enum {dig = 53};
|
||||||
/* (a << 32) | b */
|
enum {dig_u = dig-32, dig_r64 = 64-dig, bmask = ~(~0u<<(dig_r64))};
|
||||||
xary[0] = a;
|
#if defined HAVE_UINT128_T
|
||||||
xary[1] = b;
|
const uint128_t m = ((uint128_t)1 << dig) | 1;
|
||||||
x = rb_integer_unpack(xary, 2, sizeof(uint32_t), 0,
|
uint128_t x = ((uint128_t)a << 32) | b;
|
||||||
INTEGER_PACK_MSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER|
|
r = (double)(uint64_t)((x * m) >> 64);
|
||||||
INTEGER_PACK_FORCE_BIGNUM);
|
#elif defined HAVE_UINT64_T
|
||||||
|
uint64_t x = ((uint64_t)a << dig_u) +
|
||||||
/* (1 << 53) | 1 */
|
(((uint64_t)b + (a >> dig_u)) >> dig_r64);
|
||||||
mary[0] = 0x00200000;
|
r = (double)x;
|
||||||
mary[1] = 0x00000001;
|
|
||||||
m = rb_integer_unpack(mary, 2, sizeof(uint32_t), 0,
|
|
||||||
INTEGER_PACK_MSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER|
|
|
||||||
INTEGER_PACK_FORCE_BIGNUM);
|
|
||||||
|
|
||||||
x = rb_big_mul(x, m);
|
|
||||||
if (FIXNUM_P(x)) {
|
|
||||||
#if CHAR_BIT * SIZEOF_LONG > 64
|
|
||||||
r = (double)(FIX2ULONG(x) >> 64);
|
|
||||||
#else
|
#else
|
||||||
return 0.0;
|
/* shift then add to get rid of overflow */
|
||||||
|
b = (b >> dig_r64) + (((a >> dig_u) + (b & bmask)) >> dig_r64);
|
||||||
|
r = (double)a * (1 << dig_u) + b;
|
||||||
#endif
|
#endif
|
||||||
}
|
return ldexp(r, -dig);
|
||||||
else {
|
|
||||||
uint32_t uary[4];
|
|
||||||
rb_integer_pack(x, uary, numberof(uary), sizeof(uint32_t), 0,
|
|
||||||
INTEGER_PACK_MSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER);
|
|
||||||
/* r = x >> 64 */
|
|
||||||
r = (double)uary[0] * (0x10000 * (double)0x10000) + (double)uary[1];
|
|
||||||
}
|
|
||||||
return ldexp(r, -53);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE rb_cRandom;
|
VALUE rb_cRandom;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче