comparison lib/vasnprintf.c @ 15959:a18c505b7981

vasnprintf: Optimize bit search operation. * lib/vasnprintf.c (divide): Use optimizations from integer_length.c. * m4/vasnprintf.m4 (gl_PREREQ_VASNPRINTF): Require gl_DOUBLE_EXPONENT_LOCATION. * modules/vasnprintf (Files): Add m4/exponentd.m4. * modules/unistdio/u8-vasnprintf (Files): Likewise. * modules/unistdio/u8-u8-vasnprintf (Files): Likewise. * modules/unistdio/u16-vasnprintf (Files): Likewise. * modules/unistdio/u16-u16-vasnprintf (Files): Likewise. * modules/unistdio/u32-vasnprintf (Files): Likewise. * modules/unistdio/u32-u32-vasnprintf (Files): Likewise. * modules/unistdio/ulc-vasnprintf (Files): Likewise. * m4/isnand.m4 (gl_PREREQ_ISNAND): Use AC_REQUIRE.
author Bruno Haible <bruno@clisp.org>
date Sat, 15 Oct 2011 13:20:29 +0200
parents ed8603738240
children 8250f2777afc
comparison
equal deleted inserted replaced
15958:ed8603738240 15959:a18c505b7981
551 beta^(m-n-1) <= a/b < beta^(m-n+1). */ 551 beta^(m-n-1) <= a/b < beta^(m-n+1). */
552 /* Determine s. */ 552 /* Determine s. */
553 size_t s; 553 size_t s;
554 { 554 {
555 mp_limb_t msd = b_ptr[b_len - 1]; /* = b[n-1], > 0 */ 555 mp_limb_t msd = b_ptr[b_len - 1]; /* = b[n-1], > 0 */
556 s = 31; 556 /* Determine s = GMP_LIMB_BITS - integer_length (msd).
557 if (msd >= 0x10000) 557 Code copied from gnulib's integer_length.c. */
558 # if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
559 s = __builtin_clz (msd);
560 # else
561 # if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT
562 if (GMP_LIMB_BITS <= DBL_MANT_BIT)
558 { 563 {
559 msd = msd >> 16; 564 /* Use 'double' operations.
560 s -= 16; 565 Assumes an IEEE 754 'double' implementation. */
566 # define DBL_EXP_MASK ((DBL_MAX_EXP - DBL_MIN_EXP) | 7)
567 # define DBL_EXP_BIAS (DBL_EXP_MASK / 2 - 1)
568 # define NWORDS \
569 ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
570 union { double value; unsigned int word[NWORDS]; } m;
571
572 /* Use a single integer to floating-point conversion. */
573 m.value = msd;
574
575 s = GMP_LIMB_BITS
576 - (((m.word[DBL_EXPBIT0_WORD] >> DBL_EXPBIT0_BIT) & DBL_EXP_MASK)
577 - DBL_EXP_BIAS);
561 } 578 }
562 if (msd >= 0x100) 579 else
580 # undef NWORDS
581 # endif
563 { 582 {
564 msd = msd >> 8; 583 s = 31;
565 s -= 8; 584 if (msd >= 0x10000)
585 {
586 msd = msd >> 16;
587 s -= 16;
588 }
589 if (msd >= 0x100)
590 {
591 msd = msd >> 8;
592 s -= 8;
593 }
594 if (msd >= 0x10)
595 {
596 msd = msd >> 4;
597 s -= 4;
598 }
599 if (msd >= 0x4)
600 {
601 msd = msd >> 2;
602 s -= 2;
603 }
604 if (msd >= 0x2)
605 {
606 msd = msd >> 1;
607 s -= 1;
608 }
566 } 609 }
567 if (msd >= 0x10) 610 # endif
568 {
569 msd = msd >> 4;
570 s -= 4;
571 }
572 if (msd >= 0x4)
573 {
574 msd = msd >> 2;
575 s -= 2;
576 }
577 if (msd >= 0x2)
578 {
579 msd = msd >> 1;
580 s -= 1;
581 }
582 } 611 }
583 /* 0 <= s < GMP_LIMB_BITS. 612 /* 0 <= s < GMP_LIMB_BITS.
584 Copy b, shifting it left by s bits. */ 613 Copy b, shifting it left by s bits. */
585 if (s > 0) 614 if (s > 0)
586 { 615 {