Как насчет этого:
static double longRoundUp(long lng)
{
double d = (double)lng;
return lng <= (long)d ? d : Math.nextUp(d);
}
static double longRoundDown(long lng)
{
double d = (double)lng;
return lng >= (long)d ? d : Math.nextDown(d);
}
Тест:
long l1 = (1L << 55);
long l2 = (1L << 55) + 8;
long l3 = (1L << 55) + 4;
long l4 = (1L << 55) + 5;
System.out.format("Up %d %.0f%n", l1, longRoundUp(l1));
System.out.format("Up %d %.0f%n", l2, longRoundUp(l2));
System.out.format("Up %d %.0f%n", l3, longRoundUp(l3));
System.out.format("Up %d %.0f%n", l4, longRoundUp(l4));
System.out.println();
System.out.format("Down %d %.0f%n", l1, longRoundDown(l1));
System.out.format("Down %d %.0f%n", l2, longRoundDown(l2));
System.out.format("Down %d %.0f%n", l3, longRoundDown(l3));
System.out.format("Down %d %.0f%n", l4, longRoundDown(l4));
Вывод:
Up 36028797018963968 36028797018963968
Up 36028797018963976 36028797018963976
Up 36028797018963972 36028797018963976
Up 36028797018963973 36028797018963976
Down 36028797018963968 36028797018963968
Down 36028797018963976 36028797018963976
Down 36028797018963972 36028797018963968
Down 36028797018963973 36028797018963968