Fix Time subsecond precision loss from floating point arithmetic#9261
Fix Time subsecond precision loss from floating point arithmetic#9261headius merged 2 commits intojruby:jruby-10.0from
Conversation
Use integer arithmetic when computing millis/nanos from Rational Fixes Psych::Visitors::TestToRuby#test_time https://github.com/jruby/jruby/actions/runs/22045652593/job/63693879405
30ca982 to
539085c
Compare
|
Those failures are not your fault. Master merged 10.1 and something needs to be tweaked. Thank you! I have been running into this occasionally on our CI but never pinned it down. |
|
Suggested change to eliminate one diff --git a/core/src/main/java/org/jruby/RubyTime.java b/core/src/main/java/org/jruby/RubyTime.java
index d6a99b6450..5add2109db 100644
--- a/core/src/main/java/org/jruby/RubyTime.java
+++ b/core/src/main/java/org/jruby/RubyTime.java
@@ -113,6 +113,7 @@ public class RubyTime extends RubyObject {
private static final BigDecimal ONE_MILLION_BD = BigDecimal.valueOf(1000000);
private static final BigDecimal ONE_BILLION_BD = BigDecimal.valueOf(1000000000);
public static final int TIME_SCALE = 1_000_000_000;
+ public static final BigInteger TIME_SCALE_BI = BigInteger.valueOf(RubyTime.TIME_SCALE);
public static final int TIME_SCALE_DIGITS = 9;
private DateTime dt;
diff --git a/core/src/main/java/org/jruby/util/time/TimeArgs.java b/core/src/main/java/org/jruby/util/time/TimeArgs.java
index eaed31c7e5..fb445f231f 100644
--- a/core/src/main/java/org/jruby/util/time/TimeArgs.java
+++ b/core/src/main/java/org/jruby/util/time/TimeArgs.java
@@ -136,7 +136,7 @@ public class TimeArgs {
}
long subSeconds = BigInteger.valueOf(numerator)
- .multiply(BigInteger.valueOf(TIME_SCALE))
+ .multiply(RubyTime.TIME_SCALE_BI)
.divide(BigInteger.valueOf(denominator))
.longValue();
There's still a lot of narrowing conversions in this code... is there a reason why we shouldn't just use BigInteger throughout? Maybe there's a precision threshold we've already met with your logic, but going back and forth between longs and BigInteger makes me wonder. 🤔 |
96d3c41 to
0ff29d1
Compare
|
@evaniainbrooks You still have this marked as draft. Is there any more? |
|
I had another commit prepared to use BigInteger throughout, but, after reasoning through it, it does seem that this is enough. |
|
@headius marked as ready |
|
Thank you! I have some refactoring ideas that I'll push as a separate PR. |
Use integer arithmetic when computing millis/nanos from Rational
Fixes Psych::Visitors::TestToRuby#test_time
https://github.com/jruby/jruby/actions/runs/22045652593/job/63693879405