@@ -793,20 +793,23 @@ trait InternalImplementations: ModIntBase {
793
793
#[ inline]
794
794
fn add_impl ( lhs : Self , rhs : Self ) -> Self {
795
795
let modulus = Self :: modulus ( ) ;
796
- let mut val = lhs. val ( ) + rhs. val ( ) ;
797
- if val >= modulus {
798
- val -= modulus;
799
- }
796
+ let val = match lhs. val ( ) . overflowing_add ( rhs. val ( ) ) {
797
+ ( v, true ) => v. wrapping_sub ( modulus) ,
798
+ ( v, false ) => match v. overflowing_sub ( modulus) {
799
+ ( _, true ) => v,
800
+ ( w, false ) => w,
801
+ } ,
802
+ } ;
800
803
Self :: raw ( val)
801
804
}
802
805
803
806
#[ inline]
804
807
fn sub_impl ( lhs : Self , rhs : Self ) -> Self {
805
808
let modulus = Self :: modulus ( ) ;
806
- let mut val = lhs. val ( ) . wrapping_sub ( rhs. val ( ) ) ;
807
- if val >= modulus {
808
- val = val . wrapping_add ( modulus )
809
- }
809
+ let val = match lhs. val ( ) . overflowing_sub ( rhs. val ( ) ) {
810
+ ( v , true ) => v . wrapping_add ( modulus) ,
811
+ ( v , false ) => v ,
812
+ } ;
810
813
Self :: raw ( val)
811
814
}
812
815
@@ -1050,6 +1053,8 @@ impl_folding! {
1050
1053
1051
1054
#[ cfg( test) ]
1052
1055
mod tests {
1056
+ #![ allow( clippy:: unreadable_literal) ]
1057
+ use crate :: modint:: ModInt ;
1053
1058
use crate :: modint:: ModInt1000000007 ;
1054
1059
1055
1060
#[ test]
@@ -1157,4 +1162,29 @@ mod tests {
1157
1162
c /= b;
1158
1163
assert_eq ! ( expected, c) ;
1159
1164
}
1165
+
1166
+ // test `2^31 < modulus < 2^32` case
1167
+ // https://github.com/rust-lang-ja/ac-library-rs/issues/111
1168
+ #[ test]
1169
+ fn dynamic_modint_m32 ( ) {
1170
+ let m = 3221225471 ;
1171
+ ModInt :: set_modulus ( m) ;
1172
+ let f = ModInt :: new :: < u32 > ;
1173
+ assert_eq ! ( f( 1398188832 ) + f( 3184083880 ) , f( 1361047241 ) ) ;
1174
+ assert_eq ! ( f( 3013899062 ) + f( 2238406135 ) , f( 2031079726 ) ) ;
1175
+ assert_eq ! ( f( 2699997885 ) + f( 2745140255 ) , f( 2223912669 ) ) ;
1176
+ assert_eq ! ( f( 2824399978 ) + f( 2531872141 ) , f( 2135046648 ) ) ;
1177
+ assert_eq ! ( f( 36496612 ) - f( 2039504668 ) , f( 1218217415 ) ) ;
1178
+ assert_eq ! ( f( 266176802 ) - f( 1609833977 ) , f( 1877568296 ) ) ;
1179
+ assert_eq ! ( f( 713535382 ) - f( 2153383999 ) , f( 1781376854 ) ) ;
1180
+ assert_eq ! ( f( 1249965147 ) - f( 3144251805 ) , f( 1326938813 ) ) ;
1181
+ assert_eq ! ( f( 2692223381 ) * f( 2935379475 ) , f( 2084179397 ) ) ;
1182
+ assert_eq ! ( f( 2800462205 ) * f( 2822998916 ) , f( 2089431198 ) ) ;
1183
+ assert_eq ! ( f( 3061947734 ) * f( 3210920667 ) , f( 1962208034 ) ) ;
1184
+ assert_eq ! ( f( 3138997926 ) * f( 2994465129 ) , f( 1772479317 ) ) ;
1185
+ assert_eq ! ( f( 2947552629 ) / f( 576466398 ) , f( 2041593039 ) ) ;
1186
+ assert_eq ! ( f( 2914694891 ) / f( 399734126 ) , f( 1983162347 ) ) ;
1187
+ assert_eq ! ( f( 2202862138 ) / f( 1154428799 ) , f( 2139936238 ) ) ;
1188
+ assert_eq ! ( f( 3037207894 ) / f( 2865447143 ) , f( 1894581230 ) ) ;
1189
+ }
1160
1190
}
0 commit comments