@@ -54,7 +54,7 @@ pub trait SemanticSimpleConfig {
5454 return Err ( SemanticSimpleError :: InputOutOfRange ) ;
5555 }
5656 }
57- let z: BigInt = x - y;
57+ let z: BigInt = x - y. clone ( ) ;
5858 if let Some ( value_max_bits) = self . value_max_bits ( ) {
5959 if z. bits ( ) >= value_max_bits {
6060 return Err ( SemanticSimpleError :: OutputOutOfRange ) ;
@@ -376,6 +376,30 @@ pub trait SemanticSimpleConfig {
376376 Ok ( result)
377377 }
378378
379+ fn compute_largestexponent ( & self , x : & BigInt , y : & BigInt ) -> Result < BigInt , SemanticSimpleError > {
380+ if let Some ( value_max_bits) = self . value_max_bits ( ) {
381+ if x. bits ( ) >= value_max_bits || y. bits ( ) >= value_max_bits {
382+ return Err ( SemanticSimpleError :: InputOutOfRange ) ;
383+ }
384+ }
385+ if * y == BigInt :: zero ( ) || * y == BigInt :: one ( ) {
386+ return Ok ( BigInt :: zero ( ) ) ;
387+ }
388+
389+ let mut xx: BigInt = x. abs ( ) ;
390+ let yy: BigInt = y. abs ( ) ;
391+ let mut r: BigInt = BigInt :: zero ( ) ;
392+ loop {
393+ let aaa: BigInt = self . compute_divide_if ( & xx, & yy) ?;
394+ if aaa == xx {
395+ break ;
396+ }
397+ xx = aaa;
398+ r += BigInt :: one ( ) ;
399+ }
400+ Ok ( r)
401+ }
402+
379403 fn compute_equal ( & self , x : & BigInt , y : & BigInt ) -> Result < BigInt , SemanticSimpleError > {
380404 if let Some ( value_max_bits) = self . value_max_bits ( ) {
381405 if x. bits ( ) >= value_max_bits || y. bits ( ) >= value_max_bits {
@@ -529,6 +553,7 @@ mod tests {
529553 BitwiseAnd ,
530554 BitwiseOr ,
531555 BitwiseXor ,
556+ LargestExponent ,
532557 }
533558
534559 fn compute ( config : & dyn SemanticSimpleConfig , mode : ComputeMode , left : i64 , right : i64 ) -> String {
@@ -568,6 +593,7 @@ mod tests {
568593 ComputeMode :: BitwiseAnd => config. compute_bitwiseand ( & x, & y) ,
569594 ComputeMode :: BitwiseOr => config. compute_bitwiseor ( & x, & y) ,
570595 ComputeMode :: BitwiseXor => config. compute_bitwisexor ( & x, & y) ,
596+ ComputeMode :: LargestExponent => config. compute_largestexponent ( & x, & y) ,
571597 } ;
572598 match result {
573599 Ok ( value) => return value. to_string ( ) ,
@@ -1342,4 +1368,116 @@ mod tests {
13421368 assert_eq ! ( compute_bitwisexor( "-9223372036854775807" , "-9223372036854775808" ) , "18446744073709551615" ) ;
13431369 assert_eq ! ( compute_bitwisexor( "3148244321913096809130" , "1574122160956548404565" ) , "4722366482869645213695" ) ;
13441370 }
1371+
1372+ fn compute_largestexponent ( left : i64 , right : i64 ) -> String {
1373+ let config = SemanticSimpleConfigLimited :: new ( 32 ) ;
1374+ compute ( & config, ComputeMode :: LargestExponent , left, right)
1375+ }
1376+
1377+ #[ test]
1378+ fn test_230000_largestexponent ( ) {
1379+ assert_eq ! ( compute_largestexponent( -4 , -5 ) , "0" ) ;
1380+ assert_eq ! ( compute_largestexponent( -4 , -4 ) , "1" ) ;
1381+ assert_eq ! ( compute_largestexponent( -4 , -3 ) , "0" ) ;
1382+ assert_eq ! ( compute_largestexponent( -4 , -2 ) , "2" ) ;
1383+ assert_eq ! ( compute_largestexponent( -4 , -1 ) , "0" ) ;
1384+ assert_eq ! ( compute_largestexponent( -4 , 0 ) , "0" ) ;
1385+ assert_eq ! ( compute_largestexponent( -4 , 1 ) , "0" ) ;
1386+ assert_eq ! ( compute_largestexponent( -4 , 2 ) , "2" ) ;
1387+ assert_eq ! ( compute_largestexponent( -4 , 3 ) , "0" ) ;
1388+ assert_eq ! ( compute_largestexponent( -4 , 4 ) , "1" ) ;
1389+ assert_eq ! ( compute_largestexponent( -4 , 5 ) , "0" ) ;
1390+ assert_eq ! ( compute_largestexponent( -4 , 6 ) , "0" ) ;
1391+ assert_eq ! ( compute_largestexponent( -4 , 7 ) , "0" ) ;
1392+ assert_eq ! ( compute_largestexponent( -4 , 8 ) , "0" ) ;
1393+ assert_eq ! ( compute_largestexponent( 0 , -2 ) , "0" ) ;
1394+ assert_eq ! ( compute_largestexponent( 0 , -1 ) , "0" ) ;
1395+ assert_eq ! ( compute_largestexponent( 0 , 0 ) , "0" ) ;
1396+ assert_eq ! ( compute_largestexponent( 0 , 1 ) , "0" ) ;
1397+ assert_eq ! ( compute_largestexponent( 0 , 2 ) , "0" ) ;
1398+ assert_eq ! ( compute_largestexponent( 1 , -1 ) , "0" ) ;
1399+ assert_eq ! ( compute_largestexponent( 1 , -1 ) , "0" ) ;
1400+ assert_eq ! ( compute_largestexponent( 1 , 0 ) , "0" ) ;
1401+ assert_eq ! ( compute_largestexponent( 1 , 1 ) , "0" ) ;
1402+ assert_eq ! ( compute_largestexponent( 1 , 2 ) , "0" ) ;
1403+ assert_eq ! ( compute_largestexponent( 2 , -3 ) , "0" ) ;
1404+ assert_eq ! ( compute_largestexponent( 2 , -2 ) , "1" ) ;
1405+ assert_eq ! ( compute_largestexponent( 2 , -1 ) , "0" ) ;
1406+ assert_eq ! ( compute_largestexponent( 2 , 0 ) , "0" ) ;
1407+ assert_eq ! ( compute_largestexponent( 2 , 1 ) , "0" ) ;
1408+ assert_eq ! ( compute_largestexponent( 2 , 2 ) , "1" ) ;
1409+ assert_eq ! ( compute_largestexponent( 2 , 3 ) , "0" ) ;
1410+ assert_eq ! ( compute_largestexponent( 2 , 4 ) , "0" ) ;
1411+ assert_eq ! ( compute_largestexponent( 4 , -5 ) , "0" ) ;
1412+ assert_eq ! ( compute_largestexponent( 4 , -4 ) , "1" ) ;
1413+ assert_eq ! ( compute_largestexponent( 4 , -3 ) , "0" ) ;
1414+ assert_eq ! ( compute_largestexponent( 4 , -2 ) , "2" ) ;
1415+ assert_eq ! ( compute_largestexponent( 4 , -1 ) , "0" ) ;
1416+ assert_eq ! ( compute_largestexponent( 4 , 0 ) , "0" ) ;
1417+ assert_eq ! ( compute_largestexponent( 4 , 1 ) , "0" ) ;
1418+ assert_eq ! ( compute_largestexponent( 4 , 2 ) , "2" ) ;
1419+ assert_eq ! ( compute_largestexponent( 4 , 3 ) , "0" ) ;
1420+ assert_eq ! ( compute_largestexponent( 4 , 4 ) , "1" ) ;
1421+ assert_eq ! ( compute_largestexponent( 4 , 5 ) , "0" ) ;
1422+ assert_eq ! ( compute_largestexponent( 9 , 1 ) , "0" ) ;
1423+ assert_eq ! ( compute_largestexponent( 9 , 2 ) , "0" ) ;
1424+ assert_eq ! ( compute_largestexponent( 9 , 3 ) , "2" ) ;
1425+ assert_eq ! ( compute_largestexponent( 9 , 4 ) , "0" ) ;
1426+ assert_eq ! ( compute_largestexponent( 9 , 5 ) , "0" ) ;
1427+ assert_eq ! ( compute_largestexponent( 9 , 9 ) , "1" ) ;
1428+ assert_eq ! ( compute_largestexponent( 9 , 10 ) , "0" ) ;
1429+ assert_eq ! ( compute_largestexponent( 16 , 2 ) , "4" ) ;
1430+ assert_eq ! ( compute_largestexponent( 16 , 4 ) , "2" ) ;
1431+ assert_eq ! ( compute_largestexponent( 36 , 2 ) , "2" ) ;
1432+ assert_eq ! ( compute_largestexponent( 36 , 3 ) , "2" ) ;
1433+ assert_eq ! ( compute_largestexponent( 36 , 4 ) , "1" ) ;
1434+ assert_eq ! ( compute_largestexponent( 36 , 5 ) , "0" ) ;
1435+ assert_eq ! ( compute_largestexponent( 36 , 6 ) , "2" ) ;
1436+ assert_eq ! ( compute_largestexponent( 36 , 7 ) , "0" ) ;
1437+ }
1438+
1439+ #[ test]
1440+ fn test_230000_largestexponent_big_values ( ) {
1441+ assert_eq ! ( compute_largestexponent( 0x7fffffff , 0x7fffffff ) , "1" ) ;
1442+ assert_eq ! ( compute_largestexponent( 0x7fffffff , -0x7fffffff ) , "1" ) ;
1443+ assert_eq ! ( compute_largestexponent( -0x7fffffff , 0x7fffffff ) , "1" ) ;
1444+ assert_eq ! ( compute_largestexponent( -0x7fffffff , -0x7fffffff ) , "1" ) ;
1445+ assert_eq ! ( compute_largestexponent( 0x7fffffff , 0 ) , "0" ) ;
1446+ assert_eq ! ( compute_largestexponent( -0x7fffffff , 0 ) , "0" ) ;
1447+ assert_eq ! ( compute_largestexponent( 0x7fffffff , 1 ) , "0" ) ;
1448+ assert_eq ! ( compute_largestexponent( -0x7fffffff , 1 ) , "0" ) ;
1449+ assert_eq ! ( compute_largestexponent( 0x7fffffff , 2 ) , "0" ) ;
1450+ assert_eq ! ( compute_largestexponent( -0x7fffffff , 2 ) , "0" ) ;
1451+ assert_eq ! ( compute_largestexponent( 0x7fffffff , 3 ) , "0" ) ;
1452+ assert_eq ! ( compute_largestexponent( -0x7fffffff , 3 ) , "0" ) ;
1453+ assert_eq ! ( compute_largestexponent( 0x80000000 , 1 ) , "InputOutOfRange" ) ;
1454+ assert_eq ! ( compute_largestexponent( -0x80000000 , 1 ) , "InputOutOfRange" ) ;
1455+ assert_eq ! ( compute_largestexponent( 0x80000001 , 2 ) , "InputOutOfRange" ) ;
1456+ assert_eq ! ( compute_largestexponent( -0x80000001 , 2 ) , "InputOutOfRange" ) ;
1457+ assert_eq ! ( compute_largestexponent( 1 , 0x7fffffff ) , "0" ) ;
1458+ assert_eq ! ( compute_largestexponent( 1 , -0x7fffffff ) , "0" ) ;
1459+ assert_eq ! ( compute_largestexponent( 2 , 0x7fffffff ) , "0" ) ;
1460+ assert_eq ! ( compute_largestexponent( 2 , -0x7fffffff ) , "0" ) ;
1461+ assert_eq ! ( compute_largestexponent( 1 , 0x80000000 ) , "InputOutOfRange" ) ;
1462+ assert_eq ! ( compute_largestexponent( 1 , -0x80000000 ) , "InputOutOfRange" ) ;
1463+ assert_eq ! ( compute_largestexponent( 1 , 0x80000001 ) , "InputOutOfRange" ) ;
1464+ assert_eq ! ( compute_largestexponent( 1 , -0x80000001 ) , "InputOutOfRange" ) ;
1465+ assert_eq ! ( compute_largestexponent( 0x10000 , 0x100 ) , "2" ) ;
1466+ assert_eq ! ( compute_largestexponent( -0x10000 , 0x100 ) , "2" ) ;
1467+ assert_eq ! ( compute_largestexponent( 0x1000000 , 0x1000 ) , "2" ) ;
1468+ assert_eq ! ( compute_largestexponent( -0x1000000 , 0x1000 ) , "2" ) ;
1469+ assert_eq ! ( compute_largestexponent( 0x100000000 , 0x10000 ) , "InputOutOfRange" ) ;
1470+ assert_eq ! ( compute_largestexponent( -0x100000000 , 0x10000 ) , "InputOutOfRange" ) ;
1471+ assert_eq ! ( compute_largestexponent( 0x10000000000 , 0x100000 ) , "InputOutOfRange" ) ;
1472+ assert_eq ! ( compute_largestexponent( -0x10000000000 , 0x100000 ) , "InputOutOfRange" ) ;
1473+ assert_eq ! ( compute_largestexponent( 0x10000 , -0x100 ) , "2" ) ;
1474+ assert_eq ! ( compute_largestexponent( -0x10000 , -0x100 ) , "2" ) ;
1475+ assert_eq ! ( compute_largestexponent( 0x1000000 , -0x1000 ) , "2" ) ;
1476+ assert_eq ! ( compute_largestexponent( -0x1000000 , -0x1000 ) , "2" ) ;
1477+ assert_eq ! ( compute_largestexponent( 0x100000000 , -0x10000 ) , "InputOutOfRange" ) ;
1478+ assert_eq ! ( compute_largestexponent( -0x100000000 , -0x10000 ) , "InputOutOfRange" ) ;
1479+ assert_eq ! ( compute_largestexponent( 0x10000000000 , -0x100000 ) , "InputOutOfRange" ) ;
1480+ assert_eq ! ( compute_largestexponent( -0x10000000000 , -0x100000 ) , "InputOutOfRange" ) ;
1481+ assert_eq ! ( compute_largestexponent( 0x1000001 , 0x1000 ) , "0" ) ;
1482+ }
13451483}
0 commit comments