Skip to content

Commit

Permalink
AtCoder.Internal.Barrett for 2^31 < m < 2^32
Browse files Browse the repository at this point in the history
  • Loading branch information
kzrnm committed Sep 25, 2023
1 parent 7245509 commit 4176365
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 7 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add `Deque<T>.Grow(int capacity)`

### Changed
- `AtCoder.Internal.Barrett` for `2^31` < m < `2^32`
- Fix empty `Deque<T>.GetEnumerator()`

## [3.1.0] - 2023-09-24
Expand Down Expand Up @@ -39,7 +40,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [3.0.0-pre5] - 2023-01-26
### Changed
- Fix LCPArray ¨ LcpArray
- Fix LCPArray LcpArray

## [3.0.0-pre4] - 2023-01-26
### Added
Expand Down
6 changes: 3 additions & 3 deletions Source/ac-library-csharp/Math/Internal/Barrett.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ public Barrett(uint m)
public uint Reduce(ulong z)
{
var x = InternalMath.Mul128Bit(z, IM);
var v = unchecked((uint)(z - x * Mod));
if (Mod <= v) v += Mod;
return v;
var y = x * Mod;
if (z < y) return (uint)(z - y + Mod);
return (uint)(z - y);
}

/// <summary>
Expand Down
32 changes: 29 additions & 3 deletions Test/ac-library-csharp.Test/Internal/BarrettTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public void Barrett()
}

[Fact]
public void BarrettBorder()
public void BarrettInt32Border()
{
for (uint mod = int.MaxValue; mod >= int.MaxValue - 20; mod--)
{
Expand All @@ -40,16 +40,42 @@ public void BarrettBorder()
}
foreach (var a in v)
{
long a2 = a;
ulong a2 = a;
bt.Mul(a, bt.Mul(a, a)).Should().Be((uint)(a2 * a2 % mod * a2 % mod));
foreach (var b in v)
{
long b2 = b;
ulong b2 = b;
bt.Mul(a, b).Should().Be((uint)(a2 * b2 % mod));
}
}
}
}

[Fact]
public void BarrettUInt32Border()
{
for (uint mod = uint.MaxValue; mod >= uint.MaxValue - 20; mod--)
{
var bt = new Barrett(mod);
var v = new List<uint>();
for (uint i = 0; i < 10; i++)
{
v.Add(i);
v.Add(mod - i);
v.Add(mod / 2 + i);
v.Add(mod / 2 - i);
}
foreach (var a in v)
{
ulong a2 = a;
bt.Mul(a, bt.Mul(a, a)).Should().Be((uint)(a2 * a2 % mod * a2 % mod));
foreach (var b in v)
{
ulong b2 = b;
bt.Mul(a, b).Should().Be((uint)(a2 * b2 % mod));
}
}
}
}
}
}

0 comments on commit 4176365

Please sign in to comment.