From 3b12fcf64534c07e7557112dffce16676e9c96fc Mon Sep 17 00:00:00 2001 From: Jacob Date: Sat, 6 Jan 2024 21:09:07 +0800 Subject: [PATCH] Fix trailing_ones --- .github/workflows/tests.yml | 2 +- guide/src/types.md | 2 +- integer/CHANGELOG.md | 1 + integer/src/bits.rs | 5 +--- integer/src/repr.rs | 3 --- macros/CHANGELOG.md | 1 + src/lib.rs | 9 +++++++ tests/import.rs | 51 +++++++++++++++++++++++++++---------- 8 files changed, 51 insertions(+), 23 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4b5a761..e1462c6 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - rust: [stable, 1.64] + rust: [stable, 1.64, 1.61] steps: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 diff --git a/guide/src/types.md b/guide/src/types.md index bc8711b..d38bc51 100644 --- a/guide/src/types.md +++ b/guide/src/types.md @@ -12,7 +12,7 @@ Common operations are implemented for all these numeric types, please refer to t ## Word -A `dashu_int::Word` is an unsigned integer representing a native machine word. The size of a `Word` usually depends on the platform, for example, the `Word` is `u32` on 32-bit platforms. However, the behavior can be overriden by setting the `force_bits` config flag. Since this type is not consistant across platforms, be careful to use it when writing portable programs. +A `dashu_int::Word` is an unsigned integer representing a native machine word. The size of a `Word` usually depends on the platform, for example, the `Word` is `u32` on 32-bit platforms. However, the behavior can be overriden by setting the `force_bits` config flag (e.g. add `--cfg force_bits="32"` to the environment variable `RUSTFLAGS`). Since this type is not consistant across platforms, be careful to use it when writing portable programs. Moreover, there is another type `DoubleWord` representing an integer type with double the size of a `Word`. It's the maximum integer type that can fit in a `UBig` instance without heap allocation. It's also involved in some const constructors. diff --git a/integer/CHANGELOG.md b/integer/CHANGELOG.md index 1cf0734..35c371a 100644 --- a/integer/CHANGELOG.md +++ b/integer/CHANGELOG.md @@ -6,6 +6,7 @@ - Add `UBig::from_static_words` and `IBig::from_static_words` (both Rust 1.64+) to support the `static_ubig!` and `static_ibig!` macros. - Add `is_multiple_of` and `is_multiple_of_const` (Rust 1.64+) for `UBig`/`IBig` - Constify `trailing_zeros` and `trailing_ones` of `UBig`/`IBig` (Rust 1.64+). +- `IBig::trailing_ones` bug fixed. ## 0.4.0 diff --git a/integer/src/bits.rs b/integer/src/bits.rs index 9a05dff..bb417fb 100644 --- a/integer/src/bits.rs +++ b/integer/src/bits.rs @@ -590,8 +590,6 @@ mod repr { if zero_begin < (WORD_BITS_USIZE - 1) { zero_begin } else { - // Const equivalent to: - // let zero_words: usize = words.iter().skip(1).position(|&word| word != 0).unwrap(); let mut zero_words = 1; while zero_words < words.len() { if words[zero_words] != 0 { @@ -599,10 +597,9 @@ mod repr { } zero_words += 1; } - zero_words -= 1; let zero_bits = words[zero_words].trailing_zeros() as usize; - zero_words * WORD_BITS_USIZE + zero_bits + zero_begin + (zero_words - 1) * WORD_BITS_USIZE + zero_bits + zero_begin - 1 } } diff --git a/integer/src/repr.rs b/integer/src/repr.rs index 1fca3d9..74e1bf4 100644 --- a/integer/src/repr.rs +++ b/integer/src/repr.rs @@ -138,9 +138,6 @@ impl Repr { } /// Cast the reference of `Repr` to a strong typed representation, assuming the underlying data is unsigned. - /// - /// # Panics - /// /// Panics if the `capacity` is negative #[rustversion::attr(since(1.64), const)] #[inline] diff --git a/macros/CHANGELOG.md b/macros/CHANGELOG.md index 2f9afae..e55b345 100644 --- a/macros/CHANGELOG.md +++ b/macros/CHANGELOG.md @@ -4,6 +4,7 @@ - Add `static_ubig!` and `static_ibig!` macros to support static integer creation ([#38](https://github.com/cmpute/dashu/issues/38)). - Add `static_fbig!` macro to support static float numbers creation. +- Add `static_rbig!` macro to support static rational numbers creation. ## 0.4.0 diff --git a/src/lib.rs b/src/lib.rs index f26f8f9..ea5d967 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -101,6 +101,15 @@ macro_rules! rbig { } } +#[macro_export] +#[rustversion::since(1.64)] +#[doc = include_str!("../macros/docs/static_rbig.md")] +macro_rules! static_rbig { + ($($t:tt)+) => { + $crate::__dashu_macros::static_rbig_embedded!($($t)+) + } +} + /// A verbose alias for [UBig][dashu_int::UBig] pub type Natural = dashu_int::UBig; diff --git a/tests/import.rs b/tests/import.rs index fc04747..0215fa4 100644 --- a/tests/import.rs +++ b/tests/import.rs @@ -1,45 +1,68 @@ //! Test for importing items from dashu, and do basic operations -use dashu::{float::*, integer::*, rational::*, *}; +use dashu::{rational::Relaxed, *}; #[test] #[rustfmt::skip::macros(fbig, static_fbig)] fn test_macros() { // small numbers - const A: UBig = ubig!(1234); - const B: IBig = ibig!(-1234); + const A: Natural = ubig!(1234); + const B: Integer = ibig!(-1234); assert_eq!(A + B, ibig!(0)); - static SA: &UBig = static_ubig!(1234); - static SB: &IBig = static_ibig!(-1234); + static SA: &Natural = static_ubig!(1234); + static SB: &Integer = static_ibig!(-1234); assert_eq!(SA + SB, ibig!(0)); - const C: FBig = fbig!(0x1234p-4); - const D: DBig = dbig!(12.34); + const C: Real = fbig!(0x1234p-4); + const D: Decimal = dbig!(12.34); assert!(C.to_decimal().value() > D); - static SC: &'static FBig = static_fbig!(0x1234p-4); - static SD: &'static DBig = static_dbig!(12.34); + static SC: &Real = static_fbig!(0x1234p-4); + static SD: &Decimal = static_dbig!(12.34); assert!(SC.to_decimal().value() > *SD); - const E: RBig = rbig!(2 / 5); + const E: Rational = rbig!(2 / 5); const F: Relaxed = rbig!(~2/7); assert!(E.relax() > F); + static SE: &Rational = static_rbig!(2 / 5); + static SF: &Relaxed = static_rbig!(~2/7); + assert!(SE.as_relaxed() > SF); + // large numbers let a = ubig!(0xfffffffffffffffffffffffffffffffffffffffffffffffe); let b = ibig!(-0xffffffffffffffffffffffffffffffffffffffffffffffff); assert_eq!(a + b, ibig!(-1)); + static BA: &Natural = static_ubig!(0xfffffffffffffffffffffffffffffffffffffffffffffffe); + static BB: &Integer = static_ibig!(-0xffffffffffffffffffffffffffffffffffffffffffffffff); + assert_eq!(BA + BB, ibig!(-1)); + let c = fbig!(0xffffffffffffffffffffffffffffffffffffffffffffffffp-192); let d = dbig!(999999999999999999999999999999999999999999999999999999999999e-60); assert!(c < d.to_binary().value()); - // let e = rbig!(0xfffffffffffffffffffffffffffffffffffffffffffffffe/0xffffffffffffffffffffffffffffffffffffffffffffffff); + static BC: &Real = static_fbig!(0xffffffffffffffffffffffffffffffffffffffffffffffffp-192); + static BD: &Decimal = + static_dbig!(999999999999999999999999999999999999999999999999999999999999e-60); + assert!(*BC < BD.clone().with_base_and_precision(200).value()); + let e = rbig!( - 6277101735386680763835789423207666416102355444464034512894 - / 6277101735386680763835789423207666416102355444464034512895 + 0xfffffffffffffffffffffffffffffffffffffffffffffffe + / 0xffffffffffffffffffffffffffffffffffffffffffffffff ); - let f = rbig!(~999999999999999999999999999999999999999999999999999999999998/999999999999999999999999999999999999999999999999999999999999); + let f = rbig!(~ + 999999999999999999999999999999999999999999999999999999999998 + / 999999999999999999999999999999999999999999999999999999999999); assert!(e < f.canonicalize()); + + static BE: &Rational = static_rbig!( + 0xfffffffffffffffffffffffffffffffffffffffffffffffe + / 0xffffffffffffffffffffffffffffffffffffffffffffffff + ); + static BF: &Relaxed = static_rbig!(~ + 999999999999999999999999999999999999999999999999999999999998 + / 999999999999999999999999999999999999999999999999999999999999); + assert!(*BE < BF.clone().canonicalize()); }