From 4f00b87eacbde769e34b615e2e6e5d02a3153143 Mon Sep 17 00:00:00 2001 From: Jason Bobier Date: Sun, 10 Aug 2025 18:27:08 -0400 Subject: [PATCH 1/4] Updated GCD file names. Changed GCD.swift to GreatestCommonDivisor.swift. Chagned GCDTests.swift to GreatestCommonDivisorTests.swift --- Sources/IntegerUtilities/CMakeLists.txt | 2 +- .../IntegerUtilities/{GCD.swift => GreatestCommonDivisor.swift} | 2 +- Tests/IntegerUtilitiesTests/CMakeLists.txt | 2 +- .../{GCDTests.swift => GreatestCommonDivisorTests.swift} | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename Sources/IntegerUtilities/{GCD.swift => GreatestCommonDivisor.swift} (94%) rename Tests/IntegerUtilitiesTests/{GCDTests.swift => GreatestCommonDivisorTests.swift} (100%) diff --git a/Sources/IntegerUtilities/CMakeLists.txt b/Sources/IntegerUtilities/CMakeLists.txt index db167c77..6dcac644 100644 --- a/Sources/IntegerUtilities/CMakeLists.txt +++ b/Sources/IntegerUtilities/CMakeLists.txt @@ -9,7 +9,7 @@ See https://swift.org/LICENSE.txt for license information add_library(IntegerUtilities DivideWithRounding.swift - GCD.swift + GreatestCommonDivisor.swift Rotate.swift RoundingRule.swift SaturatingArithmetic.swift diff --git a/Sources/IntegerUtilities/GCD.swift b/Sources/IntegerUtilities/GreatestCommonDivisor.swift similarity index 94% rename from Sources/IntegerUtilities/GCD.swift rename to Sources/IntegerUtilities/GreatestCommonDivisor.swift index 28e09bdb..6c1e3ea4 100644 --- a/Sources/IntegerUtilities/GCD.swift +++ b/Sources/IntegerUtilities/GreatestCommonDivisor.swift @@ -1,4 +1,4 @@ -//===--- GCD.swift --------------------------------------------*- swift -*-===// +//===--- GreatestCommonDivisor.swift --------------------------------------------*- swift -*-===// // // This source file is part of the Swift Numerics open source project // diff --git a/Tests/IntegerUtilitiesTests/CMakeLists.txt b/Tests/IntegerUtilitiesTests/CMakeLists.txt index 15376625..9fd0cd7a 100644 --- a/Tests/IntegerUtilitiesTests/CMakeLists.txt +++ b/Tests/IntegerUtilitiesTests/CMakeLists.txt @@ -10,7 +10,7 @@ See https://swift.org/LICENSE.txt for license information add_library(IntegerUtilitiesTests DivideTests.swift DoubleWidthTests.swift - GCDTests.swift + GreatestCommonDivisorTests.swift RotateTests.swift SaturatingArithmeticTests.swift ShiftTests.swift) diff --git a/Tests/IntegerUtilitiesTests/GCDTests.swift b/Tests/IntegerUtilitiesTests/GreatestCommonDivisorTests.swift similarity index 100% rename from Tests/IntegerUtilitiesTests/GCDTests.swift rename to Tests/IntegerUtilitiesTests/GreatestCommonDivisorTests.swift From d7ea57bb20dd3f223614c264f1e0d49ca24dd985 Mon Sep 17 00:00:00 2001 From: Jason Bobier Date: Sun, 10 Aug 2025 19:07:59 -0400 Subject: [PATCH 2/4] Updated gcd and tests. Updated gcd to return Magnitude. Updated tests to SwiftTesting. --- .../GreatestCommonDivisor.swift | 39 ++++++------ .../GreatestCommonDivisorTests.swift | 59 +++++++++---------- 2 files changed, 46 insertions(+), 52 deletions(-) diff --git a/Sources/IntegerUtilities/GreatestCommonDivisor.swift b/Sources/IntegerUtilities/GreatestCommonDivisor.swift index 6c1e3ea4..940dc8d1 100644 --- a/Sources/IntegerUtilities/GreatestCommonDivisor.swift +++ b/Sources/IntegerUtilities/GreatestCommonDivisor.swift @@ -1,4 +1,4 @@ -//===--- GreatestCommonDivisor.swift --------------------------------------------*- swift -*-===// +//===--- GreatestCommonDivisor.swift --------------------------*- swift -*-===// // // This source file is part of the Swift Numerics open source project // @@ -14,27 +14,22 @@ /// If both inputs are zero, the result is zero. If one input is zero, the /// result is the absolute value of the other input. /// -/// The result must be representable within its type. In particular, the gcd -/// of a signed, fixed-width integer type's minimum with itself (or zero) -/// cannot be represented, and results in a trap. -/// -/// gcd(Int.min, Int.min) // Overflow error -/// gcd(Int.min, 0) // Overflow error -/// /// [gcd]: https://en.wikipedia.org/wiki/Greatest_common_divisor @inlinable -public func gcd(_ a: T, _ b: T) -> T { - var x = a - var y = b - if x.magnitude < y.magnitude { swap(&x, &y) } - // Avoid overflow when x = signed min, y = -1. - if y.magnitude == 1 { return 1 } - // Euclidean algorithm for GCD. It's worth using Lehmer instead for larger - // integer types, but for now this is good and dead-simple and faster than - // the other obvious choice, the binary algorithm. - while y != 0 { (x, y) = (y, x%y) } - // Try to convert result to T. - if let result = T(exactly: x.magnitude) { return result } - // If that fails, produce a diagnostic. - fatalError("GCD (\(x)) is not representable as \(T.self).") +public func gcd(_ a: T, _ b: T) -> T.Magnitude { + var x = a + var y = b + + if x.magnitude < y.magnitude { + swap(&x, &y) + } + + // Euclidean algorithm for GCD. It's worth using Lehmer instead for larger + // integer types, but for now this is good and dead-simple and faster than + // the other obvious choice, the binary algorithm. + while y != 0 { + (x, y) = (y, x % y) + } + + return x.magnitude } diff --git a/Tests/IntegerUtilitiesTests/GreatestCommonDivisorTests.swift b/Tests/IntegerUtilitiesTests/GreatestCommonDivisorTests.swift index 6400732c..113952f3 100644 --- a/Tests/IntegerUtilitiesTests/GreatestCommonDivisorTests.swift +++ b/Tests/IntegerUtilitiesTests/GreatestCommonDivisorTests.swift @@ -1,4 +1,5 @@ -//===--- GCDTests.swift ---------------------------------------*- swift -*-===// +//===--- GreatestCommonDivisorTests.swift ---------------------*- swift -*-===// +//===--- GreatestCommonDivisorTests.swift ---------------------------------------*- swift -*-===// // // This source file is part of the Swift Numerics open source project // @@ -11,34 +12,32 @@ //===----------------------------------------------------------------------===// import IntegerUtilities -import XCTest +import Testing -final class IntegerUtilitiesGCDTests: XCTestCase { - func testGCDInt() { - XCTAssertEqual(gcd(0, 0), 0) - XCTAssertEqual(gcd(0, 1), 1) - XCTAssertEqual(gcd(1, 0), 1) - XCTAssertEqual(gcd(0, -1), 1) - XCTAssertEqual(gcd(1, 1), 1) - XCTAssertEqual(gcd(1, 2), 1) - XCTAssertEqual(gcd(2, 2), 2) - XCTAssertEqual(gcd(4, 2), 2) - XCTAssertEqual(gcd(6, 8), 2) - XCTAssertEqual(gcd(77, 91), 7) - XCTAssertEqual(gcd(24, -36), 12) - XCTAssertEqual(gcd(-24, -36), 12) - XCTAssertEqual(gcd(51, 34), 17) - XCTAssertEqual(gcd(64, 96), 32) - XCTAssertEqual(gcd(-64, 96), 32) - XCTAssertEqual(gcd(4*7*19, 27*25), 1) - XCTAssertEqual(gcd(16*315, 11*315), 315) - XCTAssertEqual(gcd(97*67*53*27*8, 83*67*53*9*32), 67*53*9*8) - XCTAssertEqual(gcd(Int.min, 2), 2) - - // TODO: Enable these when version compatibility allows. - // - // XCTExpectFailure{ gcd(0, Int.min) } - // XCTExpectFailure{ gcd(Int.min, 0) } - // XCTExpectFailure{ gcd(Int.min, Int.min) } - } +struct `Greatest Common Divisor Tests` { + @Test func `gcd`() async throws { + #expect(gcd(0, 0) == 0) + #expect(gcd(0, 1) == 1) + #expect(gcd(1, 0) == 1) + #expect(gcd(0, -1) == 1) + #expect(gcd(-1, 0) == 1) + #expect(gcd(1, 1) == 1) + #expect(gcd(1, 2) == 1) + #expect(gcd(2, 2) == 2) + #expect(gcd(4, 2) == 2) + #expect(gcd(6, 8) == 2) + #expect(gcd(77, 91) == 7) + #expect(gcd(24, -36) == 12) + #expect(gcd(-24, -36) == 12) + #expect(gcd(51, 34) == 17) + #expect(gcd(64, 96) == 32) + #expect(gcd(-64, 96) == 32) + #expect(gcd(4*7*19, 27*25) == 1) + #expect(gcd(16*315, 11*315) == 315) + #expect(gcd(97*67*53*27*8, 83*67*53*9*32) == 67*53*9*8) + #expect(gcd(Int.max, Int.max) == Int.max) + #expect(gcd(0, Int.min) == Int.min.magnitude) + #expect(gcd(Int.min, 0) == Int.min.magnitude) + #expect(gcd(Int.min, Int.min) == Int.min.magnitude) + } } From eaf7f8bf2a2365cbd4b11ba87cf4cfda106f2356 Mon Sep 17 00:00:00 2001 From: Jason Bobier Date: Mon, 11 Aug 2025 13:26:44 -0400 Subject: [PATCH 3/4] Removed extra line in header. --- Tests/IntegerUtilitiesTests/GreatestCommonDivisorTests.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/Tests/IntegerUtilitiesTests/GreatestCommonDivisorTests.swift b/Tests/IntegerUtilitiesTests/GreatestCommonDivisorTests.swift index 113952f3..ed088579 100644 --- a/Tests/IntegerUtilitiesTests/GreatestCommonDivisorTests.swift +++ b/Tests/IntegerUtilitiesTests/GreatestCommonDivisorTests.swift @@ -1,5 +1,4 @@ //===--- GreatestCommonDivisorTests.swift ---------------------*- swift -*-===// -//===--- GreatestCommonDivisorTests.swift ---------------------------------------*- swift -*-===// // // This source file is part of the Swift Numerics open source project // From 7dbd05662c94333bfad2599d34330a6500454755 Mon Sep 17 00:00:00 2001 From: Jason Bobier Date: Wed, 13 Aug 2025 18:11:14 -0400 Subject: [PATCH 4/4] Updated copyright dates. --- Sources/IntegerUtilities/GreatestCommonDivisor.swift | 2 +- Tests/IntegerUtilitiesTests/GreatestCommonDivisorTests.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/IntegerUtilities/GreatestCommonDivisor.swift b/Sources/IntegerUtilities/GreatestCommonDivisor.swift index 940dc8d1..7321bff2 100644 --- a/Sources/IntegerUtilities/GreatestCommonDivisor.swift +++ b/Sources/IntegerUtilities/GreatestCommonDivisor.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift Numerics open source project // -// Copyright (c) 2021-2024 Apple Inc. and the Swift Numerics project authors +// Copyright (c) 2021-2025 Apple Inc. and the Swift Numerics project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See https://swift.org/LICENSE.txt for license information diff --git a/Tests/IntegerUtilitiesTests/GreatestCommonDivisorTests.swift b/Tests/IntegerUtilitiesTests/GreatestCommonDivisorTests.swift index ed088579..f22a3d36 100644 --- a/Tests/IntegerUtilitiesTests/GreatestCommonDivisorTests.swift +++ b/Tests/IntegerUtilitiesTests/GreatestCommonDivisorTests.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift Numerics open source project // -// Copyright (c) 2021 Apple Inc. and the Swift Numerics project authors +// Copyright (c) 2021-2025 Apple Inc. and the Swift Numerics project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See https://swift.org/LICENSE.txt for license information