@@ -109,6 +109,15 @@ final class DecimalTests : XCTestCase {
109109 XCTAssertEqual ( " -5 " , Decimal ( signOf: Decimal ( - 3 ) , magnitudeOf: Decimal ( - 5 ) ) . description)
110110 }
111111
112+ func test_DescriptionWithLocale( ) {
113+ let decimal = Decimal ( string: " -123456.789 " ) !
114+ XCTAssertEqual ( decimal. toString ( with: nil ) , " -123456.789 " )
115+ let en = decimal. toString ( with: Locale ( identifier: " en_GB " ) )
116+ XCTAssertEqual ( en, " -123456.789 " )
117+ let fr = decimal. toString ( with: Locale ( identifier: " fr_FR " ) )
118+ XCTAssertEqual ( fr, " -123456,789 " )
119+ }
120+
112121 func test_BasicConstruction( ) {
113122 let zero = Decimal ( )
114123 XCTAssertEqual ( 20 , MemoryLayout< Decimal> . size)
@@ -252,6 +261,57 @@ final class DecimalTests : XCTestCase {
252261 XCTAssertEqual ( zero3. description, " 0 " )
253262 }
254263
264+ func test_stringWithLocale( ) {
265+
266+ let en_US = Locale ( identifier: " en_US " )
267+ let fr_FR = Locale ( identifier: " fr_FR " )
268+
269+ XCTAssertEqual ( Decimal ( string: " 1,234.56 " ) ! * 1000 , Decimal ( 1000 ) )
270+ XCTAssertEqual ( Decimal ( string: " 1,234.56 " , locale: en_US) ! * 1000 , Decimal ( 1000 ) )
271+ XCTAssertEqual ( Decimal ( string: " 1,234.56 " , locale: fr_FR) ! * 1000 , Decimal ( 1234 ) )
272+ XCTAssertEqual ( Decimal ( string: " 1.234,56 " , locale: en_US) ! * 1000 , Decimal ( 1234 ) )
273+ XCTAssertEqual ( Decimal ( string: " 1.234,56 " , locale: fr_FR) ! * 1000 , Decimal ( 1000 ) )
274+
275+ XCTAssertEqual ( Decimal ( string: " -1,234.56 " ) ! * 1000 , Decimal ( - 1000 ) )
276+ XCTAssertEqual ( Decimal ( string: " +1,234.56 " ) ! * 1000 , Decimal ( 1000 ) )
277+ XCTAssertEqual ( Decimal ( string: " +1234.56e3 " ) , Decimal ( 1234560 ) )
278+ XCTAssertEqual ( Decimal ( string: " +1234.56E3 " ) , Decimal ( 1234560 ) )
279+ XCTAssertEqual ( Decimal ( string: " +123456000E-3 " ) , Decimal ( 123456 ) )
280+
281+ XCTAssertNil ( Decimal ( string: " " ) )
282+ XCTAssertNil ( Decimal ( string: " x " ) )
283+ XCTAssertEqual ( Decimal ( string: " -x " ) , Decimal . zero)
284+ XCTAssertEqual ( Decimal ( string: " +x " ) , Decimal . zero)
285+ XCTAssertEqual ( Decimal ( string: " - " ) , Decimal . zero)
286+ XCTAssertEqual ( Decimal ( string: " + " ) , Decimal . zero)
287+ XCTAssertEqual ( Decimal ( string: " -. " ) , Decimal . zero)
288+ XCTAssertEqual ( Decimal ( string: " +. " ) , Decimal . zero)
289+
290+ XCTAssertEqual ( Decimal ( string: " -0 " ) , Decimal . zero)
291+ XCTAssertEqual ( Decimal ( string: " +0 " ) , Decimal . zero)
292+ XCTAssertEqual ( Decimal ( string: " -0. " ) , Decimal . zero)
293+ XCTAssertEqual ( Decimal ( string: " +0. " ) , Decimal . zero)
294+ XCTAssertEqual ( Decimal ( string: " e1 " ) , Decimal . zero)
295+ XCTAssertEqual ( Decimal ( string: " e-5 " ) , Decimal . zero)
296+ XCTAssertEqual ( Decimal ( string: " .3e1 " ) , Decimal ( 3 ) )
297+
298+ XCTAssertEqual ( Decimal ( string: " . " ) , Decimal . zero)
299+ XCTAssertEqual ( Decimal ( string: " . " , locale: en_US) , Decimal . zero)
300+ XCTAssertNil ( Decimal ( string: " . " , locale: fr_FR) )
301+
302+ XCTAssertNil ( Decimal ( string: " , " ) )
303+ XCTAssertEqual ( Decimal ( string: " , " , locale: fr_FR) , Decimal . zero)
304+ XCTAssertNil ( Decimal ( string: " , " , locale: en_US) )
305+
306+ let s1 = " 1234.5678 "
307+ XCTAssertEqual ( Decimal ( string: s1, locale: en_US) ? . description, s1)
308+ XCTAssertEqual ( Decimal ( string: s1, locale: fr_FR) ? . description, " 1234 " )
309+
310+ let s2 = " 1234,5678 "
311+ XCTAssertEqual ( Decimal ( string: s2, locale: en_US) ? . description, " 1234 " )
312+ XCTAssertEqual ( Decimal ( string: s2, locale: fr_FR) ? . description, s1)
313+ }
314+
255315 func testStringPartialMatch( ) {
256316 // This tests makes sure Decimal still has the
257317 // same behavior that it only requires the beginning
@@ -736,6 +796,37 @@ final class DecimalTests : XCTestCase {
736796 XCTAssertEqual ( - 4.98 , result. doubleValue, accuracy: 0.0001 )
737797 }
738798
799+ func test_Round( ) throws {
800+ let testCases : [ ( Double , Double , Int , Decimal . RoundingMode ) ] = [
801+ // expected, start, scale, round
802+ ( 0 , 0.5 , 0 , . down ) ,
803+ ( 1 , 0.5 , 0 , . up ) ,
804+ ( 2 , 2.5 , 0 , . bankers ) ,
805+ ( 4 , 3.5 , 0 , . bankers ) ,
806+ ( 5 , 5.2 , 0 , . plain ) ,
807+ ( 4.5 , 4.5 , 1 , . down ) ,
808+ ( 5.5 , 5.5 , 1 , . up ) ,
809+ ( 6.5 , 6.5 , 1 , . plain ) ,
810+ ( 7.5 , 7.5 , 1 , . bankers ) ,
811+
812+ ( - 1 , - 0.5 , 0 , . down ) ,
813+ ( - 2 , - 2.5 , 0 , . up ) ,
814+ ( - 2 , - 2.5 , 0 , . bankers ) ,
815+ ( - 4 , - 3.5 , 0 , . bankers ) ,
816+ ( - 5 , - 5.2 , 0 , . plain ) ,
817+ ( - 4.5 , - 4.5 , 1 , . down ) ,
818+ ( - 5.5 , - 5.5 , 1 , . up ) ,
819+ ( - 6.5 , - 6.5 , 1 , . plain ) ,
820+ ( - 7.5 , - 7.5 , 1 , . bankers ) ,
821+ ]
822+ for testCase in testCases {
823+ let ( expected, start, scale, mode) = testCase
824+ let num = Decimal ( start)
825+ let actual = try num. _round ( scale: scale, roundingMode: mode)
826+ XCTAssertEqual ( Decimal ( expected) , actual, " Failed test case: \( testCase) " )
827+ }
828+ }
829+
739830 func test_Maths( ) {
740831 for i in - 2 ... 10 {
741832 for j in 0 ... 5 {
@@ -767,6 +858,25 @@ final class DecimalTests : XCTestCase {
767858 }
768859 }
769860 }
861+
862+ XCTAssertEqual ( Decimal ( 186243 * 15673 as Int64 ) , Decimal ( 186243 ) * Decimal( 15673 ) )
863+
864+ XCTAssertEqual ( Decimal ( string: " 5538 " ) ! + Decimal( string: " 2880.4 " ) !, Decimal ( string: " 8418.4 " ) !)
865+
866+ XCTAssertEqual ( Decimal ( string: " 5538.0 " ) ! - Decimal( string: " 2880.4 " ) !, Decimal ( string: " 2657.6 " ) !)
867+ XCTAssertEqual ( Decimal ( string: " 2880.4 " ) ! - Decimal( 5538 ) , Decimal ( string: " -2657.6 " ) !)
868+ XCTAssertEqual ( Decimal ( 0x10000 ) - Decimal( 0x1000 ) , Decimal ( 0xf000 ) )
869+ #if !os(watchOS)
870+ XCTAssertEqual ( Decimal ( 0x1_0000_0000 ) - Decimal( 0x1000 ) , Decimal ( 0xFFFFF000 ) )
871+ XCTAssertEqual ( Decimal ( 0x1_0000_0000_0000 ) - Decimal( 0x1000 ) , Decimal ( 0xFFFFFFFFF000 ) )
872+ #endif
873+ XCTAssertEqual ( Decimal ( 1234_5678_9012_3456_7899 as UInt64 ) - Decimal( 1234_5678_9012_3456_7890 as UInt64 ) , Decimal ( 9 ) )
874+ XCTAssertEqual ( Decimal ( 0xffdd_bb00_8866_4422 as UInt64 ) - Decimal( 0x7777_7777 ) , Decimal ( 0xFFDD_BB00_10EE_CCAB as UInt64 ) )
875+
876+ let highBit = Decimal ( _exponent: 0 , _length: 8 , _isNegative: 0 , _isCompact: 1 , _reserved: 0 , _mantissa: ( 0x0000 , 0x0000 , 0x0000 , 0x0000 , 0x0000 , 0x0000 , 0x0000 , 0x8000 ) )
877+ let otherBits = Decimal ( _exponent: 0 , _length: 8 , _isNegative: 0 , _isCompact: 1 , _reserved: 0 , _mantissa: ( 0xffff , 0xffff , 0xffff , 0xffff , 0xffff , 0xffff , 0xffff , 0x7fff ) )
878+ XCTAssertEqual ( highBit - otherBits, Decimal ( 1 ) )
879+ XCTAssertEqual ( otherBits + Decimal( 1 ) , highBit)
770880 }
771881
772882 func testMisc( ) throws {
@@ -805,6 +915,67 @@ final class DecimalTests : XCTestCase {
805915 XCTAssertTrue ( Decimal . nan. magnitude. isNaN)
806916 XCTAssertEqual ( Decimal . leastFiniteMagnitude. magnitude, - Decimal. leastFiniteMagnitude)
807917
918+ XCTAssertEqual ( Decimal ( - 9 ) , Decimal ( 1 ) - Decimal( 10 ) )
919+ XCTAssertEqual ( Decimal ( 1.234 ) , abs ( Decimal ( 1.234 ) ) )
920+ XCTAssertEqual ( Decimal ( 1.234 ) , abs ( Decimal ( - 1.234 ) ) )
921+ XCTAssertEqual ( ( 0 as Decimal ) . magnitude, 0 as Decimal )
922+ XCTAssertEqual ( ( 1 as Decimal ) . magnitude, 1 as Decimal )
923+ XCTAssertEqual ( ( 1 as Decimal ) . magnitude, abs ( 1 as Decimal ) )
924+ XCTAssertEqual ( ( 1 as Decimal ) . magnitude, abs ( - 1 as Decimal ) )
925+ XCTAssertEqual ( ( - 1 as Decimal ) . magnitude, abs ( - 1 as Decimal ) )
926+ XCTAssertEqual ( ( - 1 as Decimal ) . magnitude, abs ( 1 as Decimal ) )
927+ XCTAssertEqual ( Decimal . greatestFiniteMagnitude. magnitude, Decimal . greatestFiniteMagnitude)
928+
929+ var a = Decimal ( 1234 )
930+ var result = try a. _multiplyByPowerOfTen ( power: 1 , roundingMode: . plain)
931+ XCTAssertEqual ( Decimal ( 12340 ) , result)
932+ a = Decimal ( 1234 )
933+ result = try a. _multiplyByPowerOfTen ( power: 2 , roundingMode: . plain)
934+ XCTAssertEqual ( Decimal ( 123400 ) , result)
935+ a = result
936+ do {
937+ result = try a. _multiplyByPowerOfTen ( power: 128 , roundingMode: . plain)
938+ XCTFail ( " Expected to throw _CalcuationError.overflow " )
939+ } catch {
940+ guard let calculationError = error as? Decimal . _CalculationError else {
941+ XCTFail ( " Expected Decimal._CalculationError, got \( error) " )
942+ return
943+ }
944+ XCTAssertEqual ( . overflow, calculationError)
945+ }
946+ a = Decimal ( 1234 )
947+ result = try a. _multiplyByPowerOfTen ( power: - 2 , roundingMode: . plain)
948+ XCTAssertEqual ( Decimal ( 12.34 ) , result)
949+ a = result
950+ do {
951+ result = try a. _multiplyByPowerOfTen ( power: - 128 , roundingMode: . plain)
952+ XCTFail ( " Expected to throw _CalcuationError.underflow " )
953+ } catch {
954+ guard let calculationError = error as? Decimal . _CalculationError else {
955+ XCTFail ( " Expected Decimal._CalculationError, got \( error) " )
956+ return
957+ }
958+ XCTAssertEqual ( . underflow, calculationError)
959+ }
960+ a = Decimal ( 1234 )
961+ result = try a. _power ( exponent: 0 , roundingMode: . plain)
962+ XCTAssertEqual ( Decimal ( 1 ) , result)
963+ a = Decimal ( 8 )
964+ result = try a. _power ( exponent: 2 , roundingMode: . plain)
965+ XCTAssertEqual ( Decimal ( 64 ) , result)
966+ a = Decimal ( - 2 )
967+ result = try a. _power ( exponent: 3 , roundingMode: . plain)
968+ XCTAssertEqual ( Decimal ( - 8 ) , result)
969+ for i in - 2 ... 10 {
970+ for j in 0 ... 5 {
971+ let power = Decimal ( i)
972+ let actual = try power. _power ( exponent: UInt ( j) , roundingMode: . plain)
973+ let expected = Decimal ( pow ( Double ( i) , Double ( j) ) )
974+ XCTAssertEqual ( expected, actual, " \( actual) == \( i) ^ \( j) " )
975+ XCTAssertEqual ( expected, try power. _power ( exponent: UInt ( j) , roundingMode: . plain) )
976+ }
977+ }
978+
808979 do {
809980 // SR-13015
810981 let a = try XCTUnwrap ( Decimal ( string: " 119.993 " ) )
@@ -946,15 +1117,26 @@ final class DecimalTests : XCTestCase {
9461117 }
9471118
9481119 func test_Significand( ) {
949- let x = - 42 as Decimal
1120+ var x = - 42 as Decimal
1121+ XCTAssertEqual ( x. significand. sign, . plus)
1122+ var y = Decimal ( sign: . plus, exponent: 0 , significand: x)
1123+ XCTAssertEqual ( y, - 42 )
1124+ y = Decimal ( sign: . minus, exponent: 0 , significand: x)
1125+ XCTAssertEqual ( y, 42 )
1126+
1127+ x = 42 as Decimal
9501128 XCTAssertEqual ( x. significand. sign, . plus)
951- let y = Decimal ( sign: . plus, exponent: 0 , significand: x)
952- XCTAssertEqual ( y. sign, . minus)
1129+ y = Decimal ( sign: . plus, exponent: 0 , significand: x)
1130+ XCTAssertEqual ( y, 42 )
1131+ y = Decimal ( sign: . minus, exponent: 0 , significand: x)
1132+ XCTAssertEqual ( y, - 42 )
9531133
9541134 let a = Decimal . leastNonzeroMagnitude
9551135 XCTAssertEqual ( Decimal ( sign: . plus, exponent: - 10 , significand: a) , 0 )
1136+ XCTAssertEqual ( Decimal ( sign: . plus, exponent: . min, significand: a) , 0 )
9561137 let b = Decimal . greatestFiniteMagnitude
9571138 XCTAssertTrue ( Decimal ( sign: . plus, exponent: 10 , significand: b) . isNaN)
1139+ XCTAssertTrue ( Decimal ( sign: . plus, exponent: . max, significand: b) . isNaN)
9581140 }
9591141
9601142 func test_ULP( ) {
0 commit comments