This is the method toNanos in class Duration
public long toNanos() {
long tempSeconds = seconds;
long tempNanos = nanos;
// TODO: Here makes me confused
if (tempSeconds < 0) {
// change the seconds and nano value to
// handle Long.MIN_VALUE case
tempSeconds = tempSeconds + 1;
tempNanos = tempNanos - NANOS_PER_SECOND;
}
long totalNanos = Math.multiplyExact(tempSeconds, NANOS_PER_SECOND);
totalNanos = Math.addExact(totalNanos, tempNanos);
return totalNanos;
}
I couldn't understand why need to do extra work when seconds is negative.
Positive numbers' max is 2^63-1 and negative numbers' min is 2^63, looks like it transfer -2^63s,-1ns to -2^63+1s,1000_000_000-1ns, but it has to particate in calculate eventually. In my view this is meaningless because Math.multiplyExact and Math.addExact will throw an Exception when numbers overflow, it doesn't change not matter the judgement existed or not

The extra work is needed for the case
Duration.ofNanos(Long.MIN_VALUE)(and some more cases which result in the same number of seconds).Duration.ofNanos(Long.MIN_VALUE)is stored as seconds=-9223372037 and nanos=145224192.The simple calculation
seconds*1_000_000_000would underflow the range of long values (and therefore the naiveMath.multiplyExact(seconds, NANOS_PER_SECOND)would throw an exception). ButDuration.ofNanos(Long.MIN_VALUE).toNanos()should not throw an exception, it should returnLong.MIN_VALUE.They could have written the condition as
if (tempSeconds <= -9223372037) { ... }and it would give the same results (i.e. throw for the same values of seconds and nanos) but such a constant is harder to maintain.