@@ -1415,6 +1415,67 @@ public double toFSpecial(
1415
1415
1416
1416
}
1417
1417
1418
+ @ CoreMethod (names = "to_r" )
1419
+ public abstract static class ToRNode extends BigDecimalCoreMethodArrayArgumentsNode {
1420
+
1421
+ @ Child private CallDispatchHeadNode createRationalNode = CallDispatchHeadNode .createPrivate ();
1422
+
1423
+ @ Specialization (guards = "isNormal(value)" )
1424
+ public Object toR (DynamicObject value ,
1425
+ @ Cached ("new()" ) FixnumOrBignumNode numeratorConversionNode ,
1426
+ @ Cached ("new()" ) FixnumOrBignumNode denominatorConversionNode ) {
1427
+ final BigDecimal bigDecimalValue = Layouts .BIG_DECIMAL .getValue (value );
1428
+
1429
+ final BigInteger numerator = getNumerator (bigDecimalValue );
1430
+ final BigInteger denominator = getDenominator (bigDecimalValue );
1431
+
1432
+ final Object numeratorAsRubyValue = numeratorConversionNode .fixnumOrBignum (numerator );
1433
+ final Object denominatorAsRubyValue = denominatorConversionNode .fixnumOrBignum (denominator );
1434
+
1435
+ return createRationalNode .call (getContext ().getCoreLibrary ().getRationalClass (), "convert" ,
1436
+ numeratorAsRubyValue , denominatorAsRubyValue );
1437
+ }
1438
+
1439
+ @ Specialization (guards = "!isNormal(value)" )
1440
+ public Object toRSpecial (
1441
+ DynamicObject value ,
1442
+ @ Cached ("create()" ) BranchProfile negInfinityProfile ,
1443
+ @ Cached ("create()" ) BranchProfile posInfinityProfile ,
1444
+ @ Cached ("create()" ) BranchProfile negZeroProfile ,
1445
+ @ Cached ("create()" ) BranchProfile nanProfile ) {
1446
+ final BigDecimalType type = Layouts .BIG_DECIMAL .getType (value );
1447
+
1448
+ switch (type ) {
1449
+ case NEGATIVE_INFINITY :
1450
+ negInfinityProfile .enter ();
1451
+ throw new RaiseException (getContext (), coreExceptions ().floatDomainErrorResultsToNegInfinity (this ));
1452
+ case POSITIVE_INFINITY :
1453
+ posInfinityProfile .enter ();
1454
+ throw new RaiseException (getContext (), coreExceptions ().floatDomainErrorResultsToInfinity (this ));
1455
+ case NAN :
1456
+ nanProfile .enter ();
1457
+ throw new RaiseException (getContext (), coreExceptions ().floatDomainErrorResultsToNaN (this ));
1458
+ case NEGATIVE_ZERO :
1459
+ negZeroProfile .enter ();
1460
+ return createRationalNode .call (getContext ().getCoreLibrary ().getRationalClass (), "convert" , 0 , 1 );
1461
+ default :
1462
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
1463
+ throw new UnsupportedOperationException ("unreachable code branch for value: " + Layouts .BIG_DECIMAL .getType (value ));
1464
+ }
1465
+ }
1466
+
1467
+ @ TruffleBoundary
1468
+ private BigInteger getNumerator (BigDecimal value ) {
1469
+ return value .scaleByPowerOfTen (value .scale ()).toBigInteger ();
1470
+ }
1471
+
1472
+ @ TruffleBoundary
1473
+ private BigInteger getDenominator (BigDecimal value ) {
1474
+ return BigInteger .TEN .pow (value .scale ());
1475
+ }
1476
+
1477
+ }
1478
+
1418
1479
@ NonStandard
1419
1480
@ CoreMethod (names = "unscaled" , visibility = Visibility .PRIVATE )
1420
1481
public abstract static class UnscaledNode extends BigDecimalCoreMethodArrayArgumentsNode {
0 commit comments