-
Notifications
You must be signed in to change notification settings - Fork 153
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implementer concern: When can subdurations lose precision? #2195
Comments
Thanks, this is good feedback. We'll discuss it in our next champions meeting. You are welcome to join in, but in the meantime do you have any potential solutions in mind? (e.g. do the balance arithmetic in the f64 domain) |
Thanks! At first I was thinking, "could we just 'fix' the test?", but untested does not mean un(der)specified, so that's a cop-out. Perhaps a concrete question to focus on here is: This is nice because it doesn't involve crossing in/out of the world of durations. And we might want to say yes, when considering If durations being unbounded implies that TotalDurationNanoseconds cannot avoid precision loss (or integer overflow, which presumably would be worse), then it seems hard to justify DifferenceTemporalInstant as a special case purely because it's crossing into the world of durations anew. Realistically, it's natural for the thing being balanced in BalanceDuration to be an array of doubles. |
To close the loop, there was previous discussion (about putting bounds on the size of Duration fields) that may be relevant to this issue. IMO, the most relevant part of that discussion probably starts with @rkirsling's comment but continues down quite a bit:
|
Importantly, balancing logic also occurs in steps 2-7 of TemporalDurationToString. This is an even worse situation than DifferenceTemporalInstant because it goes beyond f64-representability into f64-storability. Namely, the spec currently suggests that |
…nd MAX_SAFE_INTEGER https://bugs.webkit.org/show_bug.cgi?id=243323 Reviewed by Yusuke Suzuki. Duration fields are currently specified as finite integral Numbers; unless a further bound is introduced in the future, this means we'll need to use BigInt#toString for values beyond MAX_SAFE_INTEGER. (Until now we've just being using 1e21 as a maximum, since this is the cutoff for Number#toFixed.) This is somewhat unfortunate since the use of BigInt incurs a bunch of new exception logic. Furthermore, TemporalDurationToString somehow expects us to display seconds as a decimal number in a case like `Temporal.Duration.from({ microseconds: Number.MAX_VALUE, nanoseconds: Number.MAX_VALUE }).toString()`, where calculating in the Number domain produces Infinity. I've added this to my concerns in tc39/proposal-temporal#2195; for now, I think it makes the most sense to implement this as a RangeError. * JSTests/test262/expectations.yaml: * Source/JavaScriptCore/runtime/TemporalDuration.cpp: (JSC::TemporalDuration::toString const): (JSC::appendInteger): (JSC::TemporalDuration::toString): * Source/JavaScriptCore/runtime/TemporalDuration.h: * Source/JavaScriptCore/runtime/TemporalDurationPrototype.cpp: (JSC::JSC_DEFINE_HOST_FUNCTION): Canonical link: https://commits.webkit.org/252935@main
Addressed thoroughly by #2727. |
We believe this is addressed now. Duration units are specified to have upper bounds such that it should be possible to do all calculations using 84-bits of integer math (e.g., i128 or i64+i32) or two f64s. |
While I'm pleased about #2094's specifying that
Duration
fields be f64-representable, this test raises a significant practical concern about "who should be responsible for not losing precision".In particular:
Instant
s is not f64-representable, it is actually reasonable to expect that the BalanceDuration call in DifferenceTemporalInstant not be lossy?Duration
fields must be an f64 operation, otherwise what have we gained by storing them as such?The text was updated successfully, but these errors were encountered: