0

How do I preserve precision in my sum output? I think that what is happening is that the precision is exactly the same, but one option chooses to round.

public class Main {
    public static void main(String[] args) {
        final long seconds = 1637208584L;
        final long micro_of_second = 795307;
        final long sum = seconds + micro_of_second;
        System.out.println("seconds + micro_of_second: " + seconds + micro_of_second);
        System.out.println("sum:                       " + sum);
        System.out.println("equal?:                    " + (sum == seconds + micro_of_second));
    }
}

Output

seconds + micro_of_second: 1637208584795307
sum:                       1638003891
equal?:                    true
Dan
  • 3,647
  • 5
  • 20
  • 26
sdc
  • 2,603
  • 1
  • 27
  • 40
  • 1
    "*`System.out.println("seconds + micro_of_second: " + seconds + micro_of_second);`*" - What do you think that line does? – Turing85 Nov 18 '21 at 19:15
  • 1
    Please check this for the details: https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.18.1 – Mirek Pluta Nov 18 '21 at 19:19
  • By the way, tracking date-time as a count from an epoch reference is error-prone and inherently ambiguous, making it difficult to debug. I suggest you use objects instead, from *java.time* classes, and serialize to text in standard [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) formats. This has been addressed extensively on Stack Overflow, so search to learn more. `Instant.ofEpochSecond( 1_637_208_584L ).plus( 795_307L , ChronoUnit.MICROS ).toString()` … `2021-11-18T04:09:44.795307Z` – Basil Bourque Nov 18 '21 at 19:49

2 Answers2

1

The issue here isn't with precision its with the line

System.out.println("seconds + micro_of_second: " + seconds + micro_of_second);

this line implicitly converts seconds and micro_of_second to a string and concatenates them together.

so the result you are seeing is actually:

"seconds + micro_of_second: " + "1637208584" + "795307"

what you want to do is evaluate the integer addition before adding it to the string. you can accomplish this by changing that line to

System.out.println("seconds + micro_of_second: " + (seconds + micro_of_second));
scigs
  • 529
  • 1
  • 5
  • 12
1

In Java, expressions are evaluated left to right. Thus

"seconds + micro_of_second: " + seconds + micro_of_second

Is semantically identical to

("seconds + micro_of_second: " + seconds) + micro_of_second

The expression

"seconds + micro_of_second: " + seconds

evaluates to a String, where the (base 10) String-representation of seconds ("1637208584") is appended to the String "seconds + micro_of_second: ". resulting in the String "seconds + micro_of_second: 1637208584".
Then, the (base 10) String-representation of micro_of_second (795307) is appended to the String "seconds + micro_of_second: 1637208584", resulting in the String seconds + micro_of_second: 1637208584795307.

By contrast, seconds + micro_of_second adds both values (1637208584 + 795307), evaluating to the long-value 1638003891.

If we want to first add both longs, we can enforce the evaluation order by introducing parentheses:

"seconds + micro_of_second: " + (seconds + micro_of_second)

This will evaluate to the String "seconds + micro_of_second: 1638003891".

Alternatively, if we want to get the total amount of microseconds, we need to multiply the value of seconds with 1_000_000L before adding micro_of_second (since there are 1_000_000 microseconds in a second):

"micros: " + (seconds * 1_000_000L + micro_of_second)

Ideone demo


As an aside: In Java, variable names should be written in camelCase instead of snake_case (micro_of_second -> microOfSecond)

Turing85
  • 18,217
  • 7
  • 33
  • 58