|
15 | 15 | import com.oracle.truffle.api.dsl.NodeChild;
|
16 | 16 | import com.oracle.truffle.api.dsl.Specialization;
|
17 | 17 | import com.oracle.truffle.api.object.DynamicObject;
|
| 18 | +import com.oracle.truffle.api.profiles.BranchProfile; |
18 | 19 | import com.oracle.truffle.api.profiles.ConditionProfile;
|
19 | 20 | import org.truffleruby.Layouts;
|
20 | 21 | import org.truffleruby.core.cast.BooleanCastNode;
|
@@ -68,16 +69,33 @@ public DynamicObject create(long value, int digits,
|
68 | 69 | }
|
69 | 70 |
|
70 | 71 | @Specialization
|
71 |
| - public DynamicObject create(double value, NotProvided digits) { |
72 |
| - throw new RaiseException(getContext(), coreExceptions().argumentErrorCantOmitPrecision(this)); |
| 72 | + public DynamicObject create(double value, NotProvided digits, |
| 73 | + @Cached("createBinaryProfile()") ConditionProfile finiteValueProfile, |
| 74 | + @Cached("create()") BranchProfile nanProfile, |
| 75 | + @Cached("create()") BranchProfile positiveInfinityProfile, |
| 76 | + @Cached("create()") BranchProfile negativeInfinityProfile) { |
| 77 | + if (finiteValueProfile.profile(Double.isFinite(value))) { |
| 78 | + throw new RaiseException(getContext(), coreExceptions().argumentErrorCantOmitPrecision(this)); |
| 79 | + } else { |
| 80 | + return createNonFiniteBigDecimal(value, nanProfile, positiveInfinityProfile, negativeInfinityProfile); |
| 81 | + } |
73 | 82 | }
|
74 | 83 |
|
75 | 84 | @Specialization
|
76 | 85 | public DynamicObject create(double value, int digits,
|
77 |
| - @Cached("create()") BigDecimalCastNode bigDecimalCastNode) { |
78 |
| - final RoundingMode roundMode = getRoundMode(); |
79 |
| - final BigDecimal bigDecimal = (BigDecimal) bigDecimalCastNode.execute(value, roundMode); |
80 |
| - return createNormalBigDecimal(round(bigDecimal, new MathContext(digits, roundMode))); |
| 86 | + @Cached("create()") BigDecimalCastNode bigDecimalCastNode, |
| 87 | + @Cached("createBinaryProfile()") ConditionProfile finiteValueProfile, |
| 88 | + @Cached("create()") BranchProfile nanProfile, |
| 89 | + @Cached("create()") BranchProfile positiveInfinityProfile, |
| 90 | + @Cached("create()") BranchProfile negativeInfinityProfile) { |
| 91 | + if (finiteValueProfile.profile(Double.isFinite(value))) { |
| 92 | + final RoundingMode roundMode = getRoundMode(); |
| 93 | + final BigDecimal bigDecimal = (BigDecimal) bigDecimalCastNode.execute(value, roundMode); |
| 94 | + |
| 95 | + return createNormalBigDecimal(round(bigDecimal, new MathContext(digits, roundMode))); |
| 96 | + } else { |
| 97 | + return createNonFiniteBigDecimal(value, nanProfile, positiveInfinityProfile, negativeInfinityProfile); |
| 98 | + } |
81 | 99 | }
|
82 | 100 |
|
83 | 101 | @Specialization(guards = "type == NEGATIVE_INFINITY || type == POSITIVE_INFINITY")
|
@@ -249,4 +267,20 @@ private Object getValueFromString(String string, int digits) {
|
249 | 267 | }
|
250 | 268 | }
|
251 | 269 |
|
| 270 | + private DynamicObject createNonFiniteBigDecimal(double value, BranchProfile nanProfile, |
| 271 | + BranchProfile positiveInfinityProfile, BranchProfile negativeInfinityProfile) { |
| 272 | + if (Double.isNaN(value)) { |
| 273 | + nanProfile.enter(); |
| 274 | + return createSpecialBigDecimal(BigDecimalType.NAN); |
| 275 | + } else { |
| 276 | + if (value == Double.POSITIVE_INFINITY) { |
| 277 | + positiveInfinityProfile.enter(); |
| 278 | + return createSpecialBigDecimal(BigDecimalType.POSITIVE_INFINITY); |
| 279 | + } else { |
| 280 | + negativeInfinityProfile.enter(); |
| 281 | + return createSpecialBigDecimal(BigDecimalType.NEGATIVE_INFINITY); |
| 282 | + } |
| 283 | + } |
| 284 | + } |
| 285 | + |
252 | 286 | }
|
0 commit comments