@@ -410,6 +410,8 @@ private T SignalOverflow2(PrecisionContext ctx, boolean neg) {
410410 if (ctx .getHasMaxPrecision () && ctx .getHasExponentRange () &&
411411 (roundingOnOverflow == Rounding .Down || roundingOnOverflow ==
412412 Rounding .ZeroFiveUp ||
413+ (roundingOnOverflow == Rounding .OddOrZeroFiveUp ||
414+ roundingOnOverflow == Rounding .Odd ) ||
413415 (roundingOnOverflow == Rounding .Ceiling && neg ) ||
414416 (roundingOnOverflow == Rounding .Floor && !neg ))) {
415417 // Set to the highest possible value for
@@ -467,7 +469,8 @@ private boolean Round(
467469 incremented |= !fastint .isEvenNumber ();
468470 }
469471 }
470- } else if (rounding == Rounding .ZeroFiveUp ) {
472+ } else if (rounding == Rounding .ZeroFiveUp ||
473+ (rounding == Rounding .OddOrZeroFiveUp && this .thisRadix != 2 )) {
471474 int radix = this .thisRadix ;
472475 if ((accum .getLastDiscardedDigit () | accum .getOlderDiscardedDigits ()) != 0 ) {
473476 if (radix == 2 ) {
@@ -499,6 +502,9 @@ private boolean RoundGivenDigits(
499502BigInteger bigval ) {
500503 boolean incremented = false ;
501504 int radix = this .thisRadix ;
505+ if (rounding == Rounding .OddOrZeroFiveUp ) {
506+ rounding = (radix == 2 ) ? Rounding .Odd : Rounding .ZeroFiveUp ;
507+ }
502508 if (rounding == Rounding .HalfUp ) {
503509 incremented |= lastDiscarded >= (radix / 2 );
504510 } else if (rounding == Rounding .HalfEven ) {
@@ -523,6 +529,8 @@ private boolean RoundGivenDigits(
523529 (radix / 2 ) && olderDiscarded != 0 );
524530 } else if (rounding == Rounding .Up ) {
525531 incremented |= (lastDiscarded | olderDiscarded ) != 0 ;
532+ } else if (rounding == Rounding .Odd ) {
533+ incremented |= (lastDiscarded | olderDiscarded ) != 0 && bigval .testBit (0 ) == false ;
526534 } else if (rounding == Rounding .ZeroFiveUp ) {
527535 if ((lastDiscarded | olderDiscarded ) != 0 ) {
528536 if (radix == 2 ) {
@@ -725,23 +733,30 @@ public T Negate(T value, PrecisionContext ctx) {
725733 return this .ReturnQuietNaN (value , ctx );
726734 }
727735 BigInteger mant = this .helper .GetMantissa (value );
736+ T zero ;
728737 if ((flags & BigNumberFlags .FlagInfinity ) == 0 && mant .signum () == 0 ) {
729738 if ((flags & BigNumberFlags .FlagNegative ) == 0 ) {
730739 // positive 0 minus positive 0 is always positive 0
731- return this .RoundToPrecision (
732- this .helper .CreateNewWithFlags (mant , this .helper .GetExponent (value ), flags & ~BigNumberFlags .FlagNegative ),
733- ctx );
740+ zero = this .helper .CreateNewWithFlags (
741+ mant ,
742+ this .helper .GetExponent (value ),
743+ flags & ~BigNumberFlags .FlagNegative );
744+ return this .RoundToPrecision (zero , ctx );
734745 }
735746 if (ctx != null && ctx .getRounding () == Rounding .Floor ) {
736747 // positive 0 minus negative 0 is negative 0 only if
737748 // the rounding is Floor
738- return this .RoundToPrecision (
739- this .helper .CreateNewWithFlags (mant , this .helper .GetExponent (value ), flags | BigNumberFlags .FlagNegative ),
740- ctx );
749+ zero = this .helper .CreateNewWithFlags (
750+ mant ,
751+ this .helper .GetExponent (value ),
752+ flags | BigNumberFlags .FlagNegative );
753+ } else {
754+ zero = this .helper .CreateNewWithFlags (
755+ mant ,
756+ this .helper .GetExponent (value ),
757+ flags & ~BigNumberFlags .FlagNegative );
741758 }
742- return this .RoundToPrecision (
743- this .helper .CreateNewWithFlags (mant , this .helper .GetExponent (value ), flags & ~BigNumberFlags .FlagNegative ),
744- ctx );
759+ return this .RoundToPrecision (zero , ctx );
745760 }
746761 flags ^= BigNumberFlags .FlagNegative ;
747762 return this .RoundToPrecision (
@@ -863,8 +878,8 @@ public T Pi(PrecisionContext ctx) {
863878 T a = this .helper .ValueOf (1 );
864879 PrecisionContext ctxdiv = SetPrecisionIfLimited (
865880 ctx ,
866- ctx .getPrecision ().add (BigInteger .TEN )). WithRounding ( this . thisRadix == 2 ?
867- Rounding . HalfEven : Rounding .ZeroFiveUp );
881+ ctx .getPrecision ().add (BigInteger .TEN ))
882+ . WithRounding ( Rounding .OddOrZeroFiveUp );
868883 T two = this .helper .ValueOf (2 );
869884 T b = this .Divide (a , this .SquareRoot (two , ctxdiv ), ctxdiv );
870885 T four = this .helper .ValueOf (4 );
@@ -930,8 +945,7 @@ private T LnInternal(
930945 PrecisionContext ctxdiv = SetPrecisionIfLimited (
931946 ctx ,
932947 workingPrecision .add (BigInteger .valueOf (6 )))
933- .WithRounding (this .thisRadix == 2 ? Rounding .HalfEven :
934- Rounding .ZeroFiveUp );
948+ .WithRounding (Rounding .OddOrZeroFiveUp );
935949 T z = this .Add (this .NegateRaw (thisValue ), this .helper .ValueOf (1 ), null );
936950 T zpow = this .Multiply (z , z , ctxdiv );
937951 T guess = this .NegateRaw (z );
@@ -973,8 +987,7 @@ private T ExpInternal(
973987 PrecisionContext ctxdiv = SetPrecisionIfLimited (
974988 ctx ,
975989 workingPrecision .add (BigInteger .valueOf (6 )))
976- .WithRounding (this .thisRadix == 2 ? Rounding .Down :
977- Rounding .ZeroFiveUp );
990+ .WithRounding (Rounding .OddOrZeroFiveUp );
978991 BigInteger bigintN = BigInteger .valueOf (2 );
979992 BigInteger facto = BigInteger .ONE ;
980993 // Guess starts with 1 + thisValue
@@ -1059,8 +1072,7 @@ private T PowerIntegral(
10591072 PrecisionContext ctxdiv = SetPrecisionIfLimited (
10601073 ctx ,
10611074 ctx .getPrecision ().add (bigError ))
1062- .WithRounding (this .thisRadix == 2 ? Rounding .HalfEven :
1063- Rounding .ZeroFiveUp ).WithBlankFlags ();
1075+ .WithRounding (Rounding .OddOrZeroFiveUp ).WithBlankFlags ();
10641076 if (sign < 0 ) {
10651077 // Use the reciprocal for negative powers
10661078 thisValue = this .Divide (one , thisValue , ctxdiv );
@@ -1332,8 +1344,7 @@ public T Power(T thisValue, T pow, PrecisionContext ctx) {
13321344 PrecisionContext ctxdiv = SetPrecisionIfLimited (
13331345 ctx ,
13341346 ctx .getPrecision ().add (guardDigits ));
1335- ctxdiv = ctxdiv .WithRounding (this .thisRadix == 2 ? Rounding .HalfEven :
1336- Rounding .ZeroFiveUp ).WithBlankFlags ();
1347+ ctxdiv = ctxdiv .WithRounding (Rounding .OddOrZeroFiveUp ).WithBlankFlags ();
13371348 T lnresult = this .Ln (thisValue , ctxdiv );
13381349 /* System.out.println("guard= " + guardDigits + " prec=" + ctx.getPrecision()+
13391350 " newprec= " + ctxdiv.getPrecision());
@@ -1444,8 +1455,7 @@ public T Log10(T thisValue, PrecisionContext ctx) {
14441455 PrecisionContext ctxdiv = SetPrecisionIfLimited (
14451456 ctx ,
14461457 ctx .getPrecision ().add (BigInteger .TEN ))
1447- .WithRounding (this .thisRadix == 2 ? Rounding .HalfEven :
1448- Rounding .ZeroFiveUp ).WithBlankFlags ();
1458+ .WithRounding (Rounding .OddOrZeroFiveUp ).WithBlankFlags ();
14491459 T logNatural = this .Ln (thisValue , ctxdiv );
14501460 T logTen = this .LnTenConstant (ctxdiv );
14511461 // T logTen = this.Ln(this.helper.ValueOf(10), ctxdiv);
@@ -1499,8 +1509,7 @@ private T LnTenConstant(PrecisionContext ctx) {
14991509 PrecisionContext ctxdiv = SetPrecisionIfLimited (
15001510 ctx ,
15011511 ctx .getPrecision ().add (bigError ))
1502- .WithRounding (this .thisRadix == 2 ? Rounding .HalfEven :
1503- Rounding .ZeroFiveUp ).WithBlankFlags ();
1512+ .WithRounding (Rounding .OddOrZeroFiveUp ).WithBlankFlags ();
15041513 for (int i = 0 ; i < 9 ; ++i ) {
15051514 thisValue = this .SquareRoot (thisValue , ctxdiv .WithUnlimitedExponents ());
15061515 }
@@ -1563,8 +1572,7 @@ public T Ln(T thisValue, PrecisionContext ctx) {
15631572 FastInteger error = new FastInteger (10 );
15641573 BigInteger bigError = error .AsBigInteger ();
15651574 ctxdiv = SetPrecisionIfLimited (ctx , ctx .getPrecision ().add (bigError ))
1566- .WithRounding (this .thisRadix == 2 ? Rounding .HalfEven :
1567- Rounding .ZeroFiveUp ).WithBlankFlags ();
1575+ .WithRounding (Rounding .OddOrZeroFiveUp ).WithBlankFlags ();
15681576 T quarter = this .Divide (one , this .helper .ValueOf (4 ), ctxCopy );
15691577 if (this .compareTo (thisValue , quarter ) <= 0 ) {
15701578 // One quarter or less
@@ -1620,8 +1628,7 @@ public T Ln(T thisValue, PrecisionContext ctx) {
16201628 error = new FastInteger (10 );
16211629 bigError = error .AsBigInteger ();
16221630 ctxdiv = SetPrecisionIfLimited (ctx , ctx .getPrecision ().add (bigError ))
1623- .WithRounding (this .thisRadix == 2 ? Rounding .HalfEven :
1624- Rounding .ZeroFiveUp ).WithBlankFlags ();
1631+ .WithRounding (Rounding .OddOrZeroFiveUp ).WithBlankFlags ();
16251632 T smallfrac = this .Divide (one , this .helper .ValueOf (10 ), ctxdiv );
16261633 T closeToOne = this .Add (one , smallfrac , null );
16271634 // Take square root until this value
@@ -1649,8 +1656,7 @@ public T Ln(T thisValue, PrecisionContext ctx) {
16491656 error = new FastInteger (10 );
16501657 bigError = error .AsBigInteger ();
16511658 ctxdiv = SetPrecisionIfLimited (ctx , ctx .getPrecision ().add (bigError ))
1652- .WithRounding (this .thisRadix == 2 ? Rounding .HalfEven :
1653- Rounding .ZeroFiveUp ).WithBlankFlags ();
1659+ .WithRounding (Rounding .OddOrZeroFiveUp ).WithBlankFlags ();
16541660 T smallfrac = this .Divide (one , this .helper .ValueOf (16 ), ctxdiv );
16551661 T closeToOne = this .Add (one , smallfrac , null );
16561662 if (this .compareTo (thisValue , closeToOne ) >= 0 ) {
@@ -1729,8 +1735,7 @@ public T Exp(T thisValue, PrecisionContext ctx) {
17291735 PrecisionContext ctxdiv = SetPrecisionIfLimited (
17301736 ctx ,
17311737 ctx .getPrecision ().add (guardDigits ))
1732- .WithRounding (this .thisRadix == 2 ? Rounding .HalfEven :
1733- Rounding .ZeroFiveUp ).WithBlankFlags ();
1738+ .WithRounding (Rounding .OddOrZeroFiveUp ).WithBlankFlags ();
17341739 if (sign == 0 ) {
17351740 thisValue = this .RoundToPrecision (one , ctxCopy );
17361741 } else if (sign > 0 && this .compareTo (thisValue , one ) < 0 ) {
@@ -3550,8 +3555,10 @@ private T RoundToPrecisionInternal(
35503555 return this .SignalInvalidWithMessage (ctx , "Rounding was required" );
35513556 }
35523557 if (!unlimitedPrec && (rounding == Rounding .Down || rounding ==
3553- Rounding .ZeroFiveUp || (rounding == Rounding .Ceiling &&
3554- neg ) || (rounding == Rounding .Floor && !neg ))) {
3558+ Rounding .ZeroFiveUp ||
3559+ (rounding == Rounding .OddOrZeroFiveUp && this .thisRadix != 2 ) ||
3560+ (rounding == Rounding .Ceiling && neg ) || (rounding ==
3561+ Rounding .Floor && !neg ))) {
35553562 // Set to the highest possible value for
35563563 // the given precision
35573564 BigInteger overflowMant = BigInteger .ZERO ;
@@ -3758,7 +3765,10 @@ private T RoundToPrecisionInternal(
37583765 flags |= PrecisionContext .FlagOverflow |
37593766 PrecisionContext .FlagInexact | PrecisionContext .FlagRounded ;
37603767 if (!unlimitedPrec && (rounding == Rounding .Down || rounding ==
3761- Rounding .ZeroFiveUp || (rounding == Rounding .Ceiling &&
3768+ Rounding .ZeroFiveUp ||
3769+ (rounding == Rounding .OddOrZeroFiveUp || rounding == Rounding .Odd ) ||
3770+
3771+ (rounding == Rounding .Ceiling &&
37623772 neg ) || (rounding == Rounding .Floor && !neg ))) {
37633773 // Set to the highest possible value for
37643774 // the given precision
0 commit comments