If you need to optionally convert to scientific notation, for instance for a more compact number representation, here's a modifed version for that purpose:
function uintToString(uint v, bool scientific) public pure returns (string memory str) {
    if (v == 0) {
        return "0";
    }
    uint maxlength = 100;
    bytes memory reversed = new bytes(maxlength);
    uint i = 0;
    
    while (v != 0) {
        uint remainder = v % 10;
        v = v / 10;
        reversed[i++] = byte(uint8(48 + remainder));
    }
    uint zeros = 0;
    if (scientific) {
        for (uint k = 0; k < i; k++) {
            if (reversed[k] == '0') {
                zeros++;
            } else {
                break;
            }
        }
    }
    uint len = i - (zeros > 2 ? zeros : 0);
    bytes memory s = new bytes(len);
    for (uint j = 0; j < len; j++) {
        s[j] = reversed[i - j - 1];
    }
    str = string(s);
    if (scientific && zeros > 2) {
        str = string(abi.encodePacked(s, "e", uintToString(zeros, false)));
    }
}
Some unit tests:
function testUintToString() public {
    Assert.equal(Utils.uintToString(0, true), '0', '0');
    Assert.equal(Utils.uintToString(1, true), '1', '1');
    Assert.equal(Utils.uintToString(123, true), '123', '123');
    Assert.equal(Utils.uintToString(107680546035, true), '107680546035', '107680546035');
    Assert.equal(Utils.uintToString(1e9, true), '1e9', '1e9');
    Assert.equal(Utils.uintToString(1 ether, true), '1e18', '1 ether');
    Assert.equal(Utils.uintToString(550e8, true), '55e9', '55e9');
}
The code snippets above are compatible with solidity 0.6.0.