Mercurial > hg > octave-lojdl > gnulib-hg
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 { |