Skip to content

[SR-6671] Decimal.leastNonzeroMagnitude, leastNormalMagnitude should have -128 exponent #1386

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
8 changes: 4 additions & 4 deletions Foundation/Decimal.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,31 +101,31 @@ public struct Decimal {

extension Decimal {
public static let leastFiniteMagnitude = Decimal(
_exponent: 127,
_exponent: Int32(Int8.max),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think of such expression change?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's going on here, and where did this property come from? "Magnitudes" are always non-negative, but this is a huge negative number. I don't know why this property even exists, but the name and documentation are extremely misleading.

(@takasek This is tangential to your change, but this is the first I've seen this).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I haven't been respond for long time...

Referring to the code, _exponent has a precondition to conform Int8. I intend to describe the precondition.
https://github.com/apple/swift-corelibs-foundation/blob/a40cc5cb3159bf64d70cb657131a01272dc988e3/Foundation/Decimal.swift#L22-L28

More fundamental solution is to change public var _exponent: Int32 into public var _exponent: Int8 but I have no idea of the impact.

_length: 8,
_isNegative: 1,
_isCompact: 1,
_reserved: 0,
_mantissa: (0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff)
)
public static let greatestFiniteMagnitude = Decimal(
_exponent: 127,
_exponent: Int32(Int8.max),
_length: 8,
_isNegative: 0,
_isCompact: 1,
_reserved: 0,
_mantissa: (0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff)
)
public static let leastNormalMagnitude = Decimal(
_exponent: -127,
_exponent: Int32(Int8.min),
_length: 1,
_isNegative: 0,
_isCompact: 1,
_reserved: 0,
_mantissa: (0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000)
)
public static let leastNonzeroMagnitude = Decimal(
_exponent: -127,
_exponent: Int32(Int8.min),
_length: 1,
_isNegative: 0,
_isCompact: 1,
Expand Down
23 changes: 21 additions & 2 deletions TestFoundation/TestDecimal.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ class TestDecimal: XCTestCase {
("test_doubleValue", test_doubleValue),
("test_NSDecimalNumberValues", test_NSDecimalNumberValues),
("test_bridging", test_bridging),
("test_LeastMagnitude", test_LeastMagnitude),
("test_GreatestMagnitude", test_GreatestMagnitude),
]
}

Expand Down Expand Up @@ -167,9 +169,9 @@ class TestDecimal: XCTestCase {
XCTAssertEqual(smallest, Decimal.leastFiniteMagnitude)
let biggest = Decimal(_exponent: 127, _length: 8, _isNegative: 0, _isCompact: 1, _reserved: 0, _mantissa: (UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max))
XCTAssertEqual(biggest, Decimal.greatestFiniteMagnitude)
let leastNormal = Decimal(_exponent: -127, _length: 1, _isNegative: 0, _isCompact: 1, _reserved: 0, _mantissa: (1, 0, 0, 0, 0, 0, 0, 0))
let leastNormal = Decimal(_exponent: -128, _length: 1, _isNegative: 0, _isCompact: 1, _reserved: 0, _mantissa: (1, 0, 0, 0, 0, 0, 0, 0))
XCTAssertEqual(leastNormal, Decimal.leastNormalMagnitude)
let leastNonzero = Decimal(_exponent: -127, _length: 1, _isNegative: 0, _isCompact: 1, _reserved: 0, _mantissa: (1, 0, 0, 0, 0, 0, 0, 0))
let leastNonzero = Decimal(_exponent: -128, _length: 1, _isNegative: 0, _isCompact: 1, _reserved: 0, _mantissa: (1, 0, 0, 0, 0, 0, 0, 0))
XCTAssertEqual(leastNonzero, Decimal.leastNonzeroMagnitude)
let pi = Decimal(_exponent: -38, _length: 8, _isNegative: 0, _isCompact: 1, _reserved: 0, _mantissa: (0x6623, 0x7d57, 0x16e7, 0xad0d, 0xaf52, 0x4641, 0xdfa7, 0xec58))
XCTAssertEqual(pi, Decimal.pi)
Expand Down Expand Up @@ -761,6 +763,23 @@ class TestDecimal: XCTestCase {
XCTAssertEqual(1, negativeSix.raising(toPower: 0))
}

func test_LeastMagnitude() {
var result = Decimal()

var leastNormal = Decimal.leastNormalMagnitude
XCTAssertEqual(.underflow, NSDecimalMultiplyByPowerOf10(&result, &leastNormal, -1, .plain))

var leastNonzero = Decimal.leastNonzeroMagnitude
XCTAssertEqual(.underflow, NSDecimalMultiplyByPowerOf10(&result, &leastNonzero, -1, .plain))
}

func test_GreatestMagnitude() {
var result = Decimal()

var greatest = Decimal.greatestFiniteMagnitude
XCTAssertEqual(.overflow, NSDecimalMultiplyByPowerOf10(&result, &greatest, 1, .plain))
}

func test_doubleValue() {
XCTAssertEqual(NSDecimalNumber(decimal:Decimal(0)).doubleValue, 0)
XCTAssertEqual(NSDecimalNumber(decimal:Decimal(1)).doubleValue, 1)
Expand Down
4 changes: 2 additions & 2 deletions TestFoundation/TestJSONSerialization.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1301,8 +1301,8 @@ extension TestJSONSerialization {
func test_serialize_Decimal() {
XCTAssertEqual(try trySerialize([-Decimal.leastFiniteMagnitude]), "[3402823669209384634633746074317682114550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000]")
XCTAssertEqual(try trySerialize([Decimal.leastFiniteMagnitude]), "[-3402823669209384634633746074317682114550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000]")
XCTAssertEqual(try trySerialize([-Decimal.leastNonzeroMagnitude]), "[-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001]")
XCTAssertEqual(try trySerialize([Decimal.leastNonzeroMagnitude]), "[0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001]")
XCTAssertEqual(try trySerialize([-Decimal.leastNonzeroMagnitude]), "[-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001]")
XCTAssertEqual(try trySerialize([Decimal.leastNonzeroMagnitude]), "[0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001]")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests failed because of changes in this PR.

XCTAssertEqual(try trySerialize([-Decimal.greatestFiniteMagnitude]), "[-3402823669209384634633746074317682114550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000]")
XCTAssertEqual(try trySerialize([Decimal.greatestFiniteMagnitude]), "[3402823669209384634633746074317682114550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000]")
XCTAssertEqual(try trySerialize([Decimal(Int8.min), Decimal(Int8(0)), Decimal(Int8.max)]), "[-128,0,127]")
Expand Down