Skip to content

Commit

Permalink
Added nthroot and square root function to BDouble
Browse files Browse the repository at this point in the history
  • Loading branch information
Zachary Gorak authored and Zachary Gorak committed Dec 2, 2019
1 parent 67a1645 commit 6a379be
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 15 deletions.
125 changes: 115 additions & 10 deletions Sources/Swift-Big-Number-Core.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2219,7 +2219,12 @@ public struct BDouble:

public init?<T>(exactly source: T) where T : BinaryInteger
{
self.init(0.0)
let i = BInt(source)
self.init(i)
}

public init(_ src: BInt) {
self.init(src, over: BInt(1))
}

/**
Expand Down Expand Up @@ -2589,8 +2594,17 @@ public struct BDouble:
return (self.sign, self.numerator, self.denominator)
}

/**
* - returns: `True` if positive, `False` otherwise
*/
public func isPositive() -> Bool { return !self.sign }
/**
* - returns: `True` if negative, `False` otherwise
*/
public func isNegative() -> Bool { return self.sign }
/**
* - returns: `True` if 0, `False` otherwise
*/
public func isZero() -> Bool { return self.numerator.equalTo(0) }

public mutating func minimize()
Expand Down Expand Up @@ -2647,12 +2661,25 @@ public struct BDouble:
return retVal
}

// public func sqrt(precision digits: Int) -> BDouble
// {
// // let self = v
// // Find x such that x*x=v <==> x = v/x
//
// }
/**
* The power of 1/root
*
* - warning: This may take a while. This is only precise up until precision. When comparing results after this function ` use` nearlyEqual`
*/
public func nthroot(_ root: Int) -> BDouble
{
return self ** BDouble(BInt(1), over: BInt(root))
}

/**
* The square root
*
* - warning: This may take a while. This is only precise up until precision. When comparing results after this function ` use` nearlyEqual`
*/
public func squareRoot() -> BDouble
{
return self ** BDouble(BInt(1), over: BInt(2))
}

//
//
Expand Down Expand Up @@ -2682,7 +2709,9 @@ public struct BDouble:

public static func +(lhs: BDouble, rhs: Double) -> BDouble { return lhs + BDouble(rhs) }
public static func +(lhs: Double, rhs: BDouble) -> BDouble { return BDouble(lhs) + rhs }

public static func +(lhs: BDouble, rhs: BInt) -> BDouble { return lhs + BDouble(rhs) }
public static func +(lhs: BInt, rhs: BDouble) -> BDouble { return BDouble(lhs) + rhs }

public static func +=(lhs: inout BDouble, rhs: BDouble) {
let res = lhs + rhs
lhs = res
Expand Down Expand Up @@ -2735,7 +2764,7 @@ public struct BDouble:
}
public static func -(lhs: BDouble, rhs: Double) -> BDouble { return lhs - BDouble(rhs) }
public static func -(lhs: Double, rhs: BDouble) -> BDouble { return BDouble(lhs) - rhs }

public static func -(lhs: BDouble, rhs: BInt) -> BDouble { return lhs - BDouble(rhs) }
public static func -=(lhs: inout BDouble, rhs: BDouble) {
let res = lhs - rhs
lhs = res
Expand Down Expand Up @@ -2766,6 +2795,8 @@ public struct BDouble:
}
public static func *(lhs: BDouble, rhs: Double) -> BDouble { return lhs * BDouble(rhs) }
public static func *(lhs: Double, rhs: BDouble) -> BDouble { return BDouble(lhs) * rhs }
public static func *(lhs: BDouble, rhs: BInt) -> BDouble { return lhs * BDouble(rhs) }
public static func *(lhs: BInt, rhs: BDouble) -> BDouble { return BDouble(lhs) * rhs }

public static func *=(lhs: inout BDouble, rhs: BDouble) {
let res = lhs * rhs
Expand All @@ -2784,7 +2815,6 @@ public struct BDouble:
//
//

// TODO: Exponentiation function that supports Double/BDouble in the exponent
public static func **(_ base : BDouble, _ exponent : Int) -> BDouble
{
if exponent == 0
Expand All @@ -2802,6 +2832,64 @@ public struct BDouble:

return base * (base ** (exponent - 1))
}

public static func **(_ base: BDouble, _ exponent: BInt) -> BDouble
{
if exponent == 0
{
return BDouble(1)
}
if exponent == 1
{
return base
}
if exponent < 0
{
return BDouble(1) / (base ** -exponent)
}

return base * (base ** (exponent - 1))
}

/**
* - reference: http://rosettacode.org/wiki/Nth_root
*/
public static func **(_ base: BDouble, _ exponent: BDouble) -> BDouble
{
var count = base.precision

// something over 1
if BInt(limbs: exponent.denominator) == 1 {
return base**BInt(sign: exponent.sign, limbs: exponent.numerator)
}

if BInt(limbs: exponent.numerator) != 1 {
return (base ** BInt(sign: exponent.sign, limbs: exponent.numerator)) ** BDouble(sign: false, numerator: BDouble(1).numerator, denominator: exponent.denominator)
}

// we have 1/something

var previous = BDouble(1)
var ans = previous
let exp = BInt(sign: exponent.sign, limbs: exponent.denominator)
let prec = BDouble(0.1) ** (abs(base.precision) + 1)

while(true) {
previous = ans

let rlhs = BDouble(BInt(1), over:exp)
let rrhs = ((exp-1)*ans + (base / pow(ans, exp-1)))
ans = rlhs * rrhs

if abs(ans-previous) < prec {
break
}

count = count + 1
}

return ans
}

//
//
Expand All @@ -2825,6 +2913,7 @@ public struct BDouble:
return res
}
public static func /(lhs: BDouble, rhs: Double) -> BDouble { return lhs / BDouble(rhs) }
public static func /(lhs: BDouble, rhs: BInt) -> BDouble { return lhs / BDouble(rhs) }
public static func /(lhs: Double, rhs: BDouble) -> BDouble { return BDouble(lhs) / rhs }

//
Expand Down Expand Up @@ -2998,11 +3087,27 @@ public func ceil(_ base: BDouble) -> BInt

/**
* Returns a BDouble number raised to a given power.
* - warning: This may take a while
*/
public func pow(_ base : BDouble, _ exp : Int) -> BDouble {
return base**exp
}

/**
* Returns a BDouble number raised to a given power.
* - warning: This may take a while
*/
public func pow(_ base : BDouble, _ exp : BInt) -> BDouble {
return base**exp
}

/**
* - warning: This may take a while. This is only precise up until precision. When comparing results after `pow` or `** ` use` nearlyEqual`
*/
public func pow(_ base : BDouble, _ exp : BDouble) -> BDouble {
return base**exp
}

/**
* Returns the BDouble that is the smallest
*/
Expand Down
10 changes: 6 additions & 4 deletions Swift-BigNumber.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,7 @@
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = "";
GCC_C_LANGUAGE_STANDARD = gnu11;
Expand All @@ -634,6 +635,7 @@
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = "";
GCC_C_LANGUAGE_STANDARD = gnu11;
Expand Down Expand Up @@ -761,7 +763,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Mac Developer";
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = "$(SRCROOT)/Testing/Info.plist";
Expand All @@ -780,7 +782,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Mac Developer";
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = "";
GCC_OPTIMIZATION_LEVEL = fast;
Expand Down Expand Up @@ -864,7 +866,7 @@
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_IDENTITY = "Mac Developer";
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = "";
Expand All @@ -886,7 +888,7 @@
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_IDENTITY = "Mac Developer";
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = "";
Expand Down
10 changes: 9 additions & 1 deletion Tests/BDoubleTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,15 @@ class BDoubleTests : XCTestCase {
}

func testPow() {
XCTAssertEqual((BDouble("27")!**3), BDouble("19683")!)
XCTAssertEqual(pow(BDouble("27")!,BInt("3")!), BDouble("19683")!)

XCTAssertEqual((BDouble("27")!**BInt("3")!), BDouble("19683")!)
XCTAssertEqual(pow(BDouble("27")!,BInt("3")!), BDouble("19683")!)

XCTAssertTrue(BDouble.nearlyEqual(BDouble("-27")!**BDouble("1", over: "3")!, BDouble("-3")!))

XCTAssertTrue(BDouble.nearlyEqual(BDouble("4")!.nthroot(2), BDouble(2.0)))
// Test that a number to the zero power is 1
for i in 0..<100 {
XCTAssertEqual(pow(BDouble(Double(i)), 0), 1.0)
Expand Down Expand Up @@ -453,5 +462,4 @@ class BDoubleTests : XCTestCase {
}
}
}

}

0 comments on commit 6a379be

Please sign in to comment.