@@ -462,6 +462,80 @@ fn clamp<T: std::cmp::PartialOrd>(
462
462
}
463
463
}
464
464
465
+ /// The greatest common divisor (GCD) calculates the largest positive integer that divides both of the two input numbers without leaving a remainder.
466
+ #[ node_macro:: node( category( "Math: Numeric" ) ) ]
467
+ fn greatest_common_divisor < T : num_traits:: int:: PrimInt + std:: ops:: ShrAssign < i32 > + std:: ops:: SubAssign > (
468
+ _: impl Ctx ,
469
+ /// One of the two numbers for which the GCD will be calculated.
470
+ #[ implementations( u32 , u64 , i32 ) ]
471
+ value : T ,
472
+ /// The other of the two numbers for which the GCD will be calculated.
473
+ #[ implementations( u32 , u64 , i32 ) ]
474
+ other_value : T ,
475
+ ) -> T {
476
+ if value == T :: zero ( ) {
477
+ return other_value;
478
+ }
479
+ if other_value == T :: zero ( ) {
480
+ return value;
481
+ }
482
+ binary_gcd ( value, other_value)
483
+ }
484
+
485
+ /// The least common multiple (LCM) calculates the smallest positive integer that is a multiple of both of the two input numbers.
486
+ #[ node_macro:: node( category( "Math: Numeric" ) ) ]
487
+ fn least_common_multiple < T : num_traits:: ToPrimitive + num_traits:: FromPrimitive + num_traits:: identities:: Zero > (
488
+ _: impl Ctx ,
489
+ /// One of the two numbers for which the LCM will be calculated.
490
+ #[ implementations( u32 , u64 , i32 ) ]
491
+ value : T ,
492
+ /// The other of the two numbers for which the LCM will be calculated.
493
+ #[ implementations( u32 , u64 , i32 ) ]
494
+ other_value : T ,
495
+ ) -> T {
496
+ let value = value. to_i128 ( ) . unwrap ( ) ;
497
+ let other_value = other_value. to_i128 ( ) . unwrap ( ) ;
498
+
499
+ if value == 0 || other_value == 0 {
500
+ return T :: zero ( ) ;
501
+ }
502
+ let gcd = binary_gcd ( value, other_value) ;
503
+
504
+ T :: from_i128 ( ( value * other_value) . abs ( ) / gcd) . unwrap ( )
505
+ }
506
+
507
+ fn binary_gcd < T : num_traits:: int:: PrimInt + std:: ops:: ShrAssign < i32 > + std:: ops:: SubAssign > ( mut a : T , mut b : T ) -> T {
508
+ if a == T :: zero ( ) {
509
+ return b;
510
+ }
511
+ if b == T :: zero ( ) {
512
+ return a;
513
+ }
514
+
515
+ let mut shift = 0 ;
516
+ while ( a | b) & T :: one ( ) == T :: zero ( ) {
517
+ a >>= 1 ;
518
+ b >>= 1 ;
519
+ shift += 1 ;
520
+ }
521
+
522
+ while a & T :: one ( ) == T :: zero ( ) {
523
+ a >>= 1 ;
524
+ }
525
+
526
+ while b != T :: zero ( ) {
527
+ while b & T :: one ( ) == T :: zero ( ) {
528
+ b >>= 1 ;
529
+ }
530
+ if a > b {
531
+ std:: mem:: swap ( & mut a, & mut b) ;
532
+ }
533
+ b -= a;
534
+ }
535
+
536
+ a << shift
537
+ }
538
+
465
539
/// The equality operation (==) compares two values and returns true if they are equal, or false if they are not.
466
540
#[ node_macro:: node( category( "Math: Logic" ) ) ]
467
541
fn equals < U : std:: cmp:: PartialEq < T > , T > (
0 commit comments