Skip to content

Commit

Permalink
Merge pull request #82 from tingwoo/decExpansionFix
Browse files Browse the repository at this point in the history
Fixed decimalExpansion
  • Loading branch information
mkrd authored Mar 1, 2024
2 parents 78dcdcb + 275e8a4 commit 158f802
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 37 deletions.
87 changes: 50 additions & 37 deletions Sources/BigNumber/Swift-Big-Number-Core.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2545,47 +2545,60 @@ public struct BDouble:
*/
public func decimalExpansion(precisionAfterDecimalPoint precision: Int, rounded : Bool = true) -> String
{
var currentPrecision = precision
var currentPrecision = precision

if(rounded && precision > 0) {
currentPrecision = currentPrecision + 1
}
if rounded {
currentPrecision += 1
}

let multiplier = [10].exponentiating(currentPrecision)
let limbs = self.numerator.multiplyingBy(multiplier).divMod(self.denominator).quotient
var res = BInt(limbs: limbs).description

if currentPrecision <= res.count
{
let multiplier = [10].exponentiating(currentPrecision)
let limbs = self.numerator.multiplyingBy(multiplier).divMod(self.denominator).quotient
var res = BInt(limbs: limbs).description

if rounded {
var digits: [Int] = Array(res).map({ char in Int(char.description)! })
let carry: Int = digits.removeLast() >= 5 ? 1 : 0
var counter: Int = digits.count - 1

if carry == 1 {
while counter >= 0 {
if digits[counter] + 1 == 10 {
digits[counter] = 0
} else {
digits[counter] += 1
break
}
counter -= 1
}

if counter == -1 {
digits.insert(1, at: 0)
}
}

let digitsArray = digits.map { String($0) }
res = digitsArray.joined()

currentPrecision -= 1
if res == "" { res = "0" }
}

if currentPrecision <= res.count {
res.insert(".", at: res.index(res.startIndex, offsetBy: res.count - currentPrecision))
if res.hasPrefix(".") { res = "0" + res }
else if res.hasSuffix(".") { res += "0" }
}
else
{
res = "0." + String(repeating: "0", count: currentPrecision - res.count) + res
}

var retVal = self.isNegative() && !limbs.equalTo(0) ? "-" + res : res

if(rounded && precision > 0) {

let lastDigit = Int(retVal.suffix(1))! // this should always be a number
let secondDigit = retVal.suffix(2).prefix(1) // this could be a decimal

retVal = String(retVal.prefix(retVal.count-2))
if (secondDigit != ".") {
if lastDigit >= 5 {
retVal = retVal + String(Int(secondDigit)! + 1)
} else {
retVal = retVal + String(Int(secondDigit)!)
}
} else {
retVal = retVal + "." + String(lastDigit)
}
}
if res.hasPrefix(".") {
res = "0" + res
}
} else {
res = "0." + String(repeating: "0", count: currentPrecision - res.count) + res
}

if currentPrecision == 0 {
res += "0"
}

let retVal = self.isNegative() && !limbs.equalTo(0) ? "-" + res : res

return retVal
return retVal
}

public func hash(into hasher: inout Hasher) {
Expand Down
16 changes: 16 additions & 0 deletions Tests/BigNumberTests/BDoubleTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,14 @@ class BDoubleTests : XCTestCase {
("-0.00009", "0.0000", 4),
("-0.00009", "-0.00009", 5),
("-0.00009", "-0.000090", 6),
("0.999805", "0.0", 0),
("0.999805", "0.9", 1),
("0.999805", "0.99", 2),
("0.999805", "0.999", 3),
("0.999805", "0.9998", 4),
("0.999805", "0.99980", 5),
("0.999805", "0.999805", 6),
("0.999805", "0.9998050", 7)
]

for (original, test, precision) in testValues
Expand All @@ -192,6 +200,14 @@ class BDoubleTests : XCTestCase {
("-0.00009", "-0.0001", 4),
("-0.00009", "-0.00009", 5),
("-0.00009", "-0.000090", 6),
("0.999805", "1.0", 0),
("0.999805", "1.0", 1),
("0.999805", "1.00", 2),
("0.999805", "1.000", 3),
("0.999805", "0.9998", 4),
("0.999805", "0.99981", 5),
("0.999805", "0.999805", 6),
("0.999805", "0.9998050", 7),
]

for (original, test, precision) in testValues
Expand Down

0 comments on commit 158f802

Please sign in to comment.