[Java] Keep track of the product start and end
We can separately compute the start and end part of the number (as well as the number of trailing zeros).\nExample (with smaller numbers):\n\n    999[999]999 * 
We can separately compute the start and end part of the number (as well as the number of trailing zeros).\nExample (with smaller numbers):\n```\n    999[999]999 * 99 // start = 999, end = 999\n =  989[99999]901 // start = 989, end = 901 => same as computing separately with 999 * 99 = 98901\n```\n\nUsing `long` provides enough precision to pass the tests (though I don\'t have a formal proof yet).\nGiven that input numbers are smaller than 10^6 and the max value of a long is (roughly) 9 * 10^18, we need to keep start and end smaller than 9 * 10^12.\n\nEdit: we actually need to use `double` for start, to have enough precision to pass new tests. Thanks @DIMITR for the comment!\n\n```\npublic static final long LIMIT = 1_000_000_000_000l; // keep start/end smaller than 10^12\n    \npublic String abbreviateProduct(int left, int right) {\n    long end = 1; // end part of the product (or the whole number if small enough)\n    long nZeros = 0; // trailing zeros\n    boolean usedModulo = false;\n    for (int n = left; n <= right; n++) {\n        end *= n;\n\n        while (end % 10 == 0) { // extract trailing zeros into nZeros\n            end /= 10;\n            nZeros++;\n        }\n\n        if (end >= LIMIT) { // truncate if needed\n            end %= LIMIT;\n            usedModulo = true;\n        }\n    }\n\n    if (!usedModulo && end < 10_000_000_000l) { // doesn\'t need abbreviation below 10^10\n        return String.format("%de%d", end, nZeros);\n    }\n\n    double start = 1; // start part of the product\n    for (int n = left; n <= right; n++) {\n        start *= n;\n\n        while (start >= LIMIT) { // truncate if needed\n            start /= 10;\n        }\n    }\n\n    return buildAbbreviation(usedModulo, start, end, nZeros);\n}\n\nprivate String buildAbbreviation(boolean usedModulo, double start, long end, long nZeros) {\n    while (start >= 100_000) { // keep the 5 first digits\n        start /= 10;\n    }\n\n    end %= 100_000; // keep the last 5 digits\n\n    return String.format("%d...%05de%d", (int) start, end, nZeros); // zero-padding of the end\n}\n```\n\nQuestions and comments welcome!
['Math', 'Java']