diff --git a/Interop-BridgingHeader/.gitignore b/Interop-BridgingHeader/.gitignore new file mode 100644 index 0000000..0023a53 --- /dev/null +++ b/Interop-BridgingHeader/.gitignore @@ -0,0 +1,8 @@ +.DS_Store +/.build +/Packages +xcuserdata/ +DerivedData/ +.swiftpm/configuration/registries.json +.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata +.netrc diff --git a/Interop-BridgingHeader/Package.swift b/Interop-BridgingHeader/Package.swift new file mode 100644 index 0000000..515eed9 --- /dev/null +++ b/Interop-BridgingHeader/Package.swift @@ -0,0 +1,24 @@ +// swift-tools-version: 6.0 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "Interop-BridgingHeader", + platforms: [.macOS(.v15)], + products: [ + .library(name: "CMath", targets: ["CMath"]), + .executable(name: "Interop-BridgingHeader", targets: ["Interop-BridgingHeader"]) + ], + targets: [ + // Targets are the basic building blocks of a package, defining a module or a test suite. + // Targets can depend on other targets in this package and products from dependencies. + .target( + name: "CMath"), + .executableTarget( + name: "Interop-BridgingHeader", + dependencies: ["CMath"], + swiftSettings: [.interoperabilityMode(.C)] + ), + ] +) diff --git a/Interop-BridgingHeader/Sources/CMath/cmath.c b/Interop-BridgingHeader/Sources/CMath/cmath.c new file mode 100644 index 0000000..8b39a07 --- /dev/null +++ b/Interop-BridgingHeader/Sources/CMath/cmath.c @@ -0,0 +1,75 @@ +// +// cmath.c +// CMath +// +// Created by TheAlgorithm476 on 28/03/2025. +// + +#include +#include "add_nums.h" +#include "sub_nums.h" +#include "mul_nums.h" +#include "div_nums.h" +#include "spc_nums.h" + +double add_nums(double a, double b) { + return a + b; +} + +double sub_nums(double a, double b) { + return b - a; +} + +double mul_nums(double a, double b) { + return a * b; +} + +double div_nums(double a, double b) { + if (a == 0) return 0; // Cannot divide by 0 + + return b / a; +} + +// Uses "poor man's pow" to determine the power of a fractional exponent. +double pow(double x, double exp) { + if (x == 0) return 0; + if (exp == 0) return 1; + if (exp < 0) return 1 / pow(x, -exp); + + int full_part = (int) exp; + double frac_part = exp - full_part; + double result = 1.0; + + // int pow + for (size_t i = 0; i < full_part; i++) { + result *= x; + } + + // Approximate fraction + if (frac_part != 0) { + double temp = 1.0; + double term = 1.0; + + for (size_t i = 1; i < POOR_MANS_POW_GUESSES; i++) { + term *= (frac_part * (x - 1)) / i; + temp += term; + } + + result *= temp; + } + + return result; +} + +// Uses Newton's Square Root to get a decent guess of the sqrt. +double sqrt(double x) { + if (x <= 0) return 0; // Negative roots are way out of scope for this thesis. + + double guess = x / 2.0; + + for (size_t i = 0; i < NEWTONIAN_DIV_GUESSES; i++) { + guess = (guess + x / guess) / 2.0; + } + + return guess; +} diff --git a/Interop-BridgingHeader/Sources/CMath/include/CMath.h b/Interop-BridgingHeader/Sources/CMath/include/CMath.h index e1c7af1..0e6dd30 100644 --- a/Interop-BridgingHeader/Sources/CMath/include/CMath.h +++ b/Interop-BridgingHeader/Sources/CMath/include/CMath.h @@ -1,5 +1,5 @@ // -// CMath-Bridging-Header.h +// CMath.h // Interop-BridgingHeader // // Created by TheAlgorithm476 on 09/04/2025. diff --git a/Interop-BridgingHeader/Sources/CMath/include/add_nums.h b/Interop-BridgingHeader/Sources/CMath/include/add_nums.h new file mode 100644 index 0000000..6c98505 --- /dev/null +++ b/Interop-BridgingHeader/Sources/CMath/include/add_nums.h @@ -0,0 +1,13 @@ +// +// add_nums.h +// CMath +// +// Created by TheAlgorithm476 on 28/03/2025. +// + +#ifndef __ADD_NUMS_H +#define __ADD_NUMS_H + +double add_nums(double a, double b); + +#endif // __ADD_NUMS_H diff --git a/Interop-BridgingHeader/Sources/CMath/include/div_nums.h b/Interop-BridgingHeader/Sources/CMath/include/div_nums.h new file mode 100644 index 0000000..f9167c5 --- /dev/null +++ b/Interop-BridgingHeader/Sources/CMath/include/div_nums.h @@ -0,0 +1,13 @@ +// +// div_nums.h +// CMath +// +// Created by TheAlgorithm476 on 28/03/2025. +// + +#ifndef __DIV_NUMS_H +#define __DIV_NUMS_H + +double div_nums(double a, double b); + +#endif // __DIV_NUMS_H diff --git a/Interop-BridgingHeader/Sources/CMath/include/mul_nums.h b/Interop-BridgingHeader/Sources/CMath/include/mul_nums.h new file mode 100644 index 0000000..ccbc5a9 --- /dev/null +++ b/Interop-BridgingHeader/Sources/CMath/include/mul_nums.h @@ -0,0 +1,13 @@ +// +// mul_nums.h +// CMath +// +// Created by TheAlgorithm476 on 28/03/2025. +// + +#ifndef __MUL_NUMS_H +#define __MUL_NUMS_H + +double mul_nums(double a, double b); + +#endif // __MUL_NUMS_H diff --git a/Interop-BridgingHeader/Sources/CMath/include/spc_nums.h b/Interop-BridgingHeader/Sources/CMath/include/spc_nums.h new file mode 100644 index 0000000..8e456bc --- /dev/null +++ b/Interop-BridgingHeader/Sources/CMath/include/spc_nums.h @@ -0,0 +1,17 @@ +// +// spc_nums.h +// CMath +// +// Created by TheAlgorithm476 on 28/03/2025. +// + +#ifndef __SPC_NUMS_H +#define __SPC_NUMS_H + +#define POOR_MANS_POW_GUESSES 12 +#define NEWTONIAN_DIV_GUESSES 12 + +double pow(double x, double exp); +double sqrt(double x); + +#endif // __SPC_NUMS_H diff --git a/Interop-BridgingHeader/Sources/CMath/include/sub_nums.h b/Interop-BridgingHeader/Sources/CMath/include/sub_nums.h new file mode 100644 index 0000000..00439e9 --- /dev/null +++ b/Interop-BridgingHeader/Sources/CMath/include/sub_nums.h @@ -0,0 +1,13 @@ +// +// sub_nums.h +// CMath +// +// Created by TheAlgorithm476 on 28/03/2025. +// + +#ifndef __SUB_NUMS_H +#define __SUB_NUMS_H + +double sub_nums(double a, double b); + +#endif // __SUB_NUMS_H diff --git a/Interop-BridgingHeader/Sources/Interop-BridgingHeader/main.swift b/Interop-BridgingHeader/Sources/Interop-BridgingHeader/main.swift index 44e20d5..e694491 100644 --- a/Interop-BridgingHeader/Sources/Interop-BridgingHeader/main.swift +++ b/Interop-BridgingHeader/Sources/Interop-BridgingHeader/main.swift @@ -1,4 +1,96 @@ -// The Swift Programming Language -// https://docs.swift.org/swift-book +import CMath +import Foundation -print("Hello, world!") +func readNumber(prompt: String) -> Double? { + print(prompt, terminator: " ") + + if let input = readLine(), let number = Double(input) { + return number + } else { + print("ERROR: Input was not a valid number!") + return nil + } +} + +func main() { + while true { + print(""" + Console Calculator -- Operations: + 1 - Addition + 2 - Subtraction + 3 - Multiplication + 4 - Division + 5 - Power + 6 - Square Root + + q - Quit the application + """) + print("Please enter your choice: ", terminator: "") + + if let operation = readLine() { + if operation.lowercased( ) == "q" { + break + } + + switch operation { + case "1": + if let number1 = readNumber(prompt: "Please enter the first number:"), + let number2 = readNumber(prompt: "Please enter the second number:") { + let result = add_nums(number1, number2) + print("Result: \(result)") + } + + case "2": + if let number1 = readNumber(prompt: "Please enter the first number:"), + let number2 = readNumber(prompt: "Please enter the second number:") { + let result = sub_nums(number1, number2) + print("Result: \(result)") + } + + case "3": + if let number1 = readNumber(prompt: "Please enter the first number:"), + let number2 = readNumber(prompt: "Please enter the second number:") { + let result = mul_nums(number1, number2) + print("Result: \(result)") + } + + case "4": + if let number1 = readNumber(prompt: "Please enter the first number:"), + let number2 = readNumber(prompt: "Please enter the second number:") { + if number2 == 0 { + print("ERROR: Division by zero!") + continue + } + + let result = div_nums(number1, number2) + print("Result: \(result)") + } + + case "5": + if let number1 = readNumber(prompt: "Please enter the base:"), + let number2 = readNumber(prompt: "Please enter the exponent:") { + let result = pow(number1, number2) + print("Result: \(result)") + } + + case "6": + if let number = readNumber(prompt: "Please enter the number to calculate the square root for:") { + if number < 0 { + print("ERROR: Cannot take the Square Root of a negative number!") + continue + } + + let result = sqrt(number) + print("Result: \(result)") + } + + default: + print("ERROR: Invalid operation!") + } + } else { + break + } + } +} + +main()