2

How do I convert an "int" type value (including negative integers) to a "string" type value in Solidity? I suppose I could convert it into a bytes32, and then convert it to a string, but I feel that it would cost a lot of gas. What is the least expensive way to do this?

1

2 Answers 2

1

Hey there is no explicit int to string conversion in solidity. You could use a function like:

function toBytes(int x, int digits) returns (bytes b) {
    b = new bytes(digits);
    for (uint i = 0; i < digits; i++)
        b[i] = byte(uint8(uint(x));
}
1
  • 1
    Please focus on an answer for the actual question. Thanks :)
    – eth
    Jul 5, 2016 at 17:22
0
    function _uintToString(uint value) private pure returns (string memory) {
        if (value == 0) {
            return "0";
        }
        uint temp = value;
        uint digits;
        while (temp != 0) {
            ++digits;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            --digits;
            buffer[digits] = bytes1(uint8(48 + uint(value % 10)));
            value /= 10;
        }

        return string(buffer);
    }

    function uintToString(uint value) internal pure returns (string memory) {
        return _uintToString(value);
    }

    /*
     * @dev Converts a `uint` to its ASCII `string` decimal representation.
     * @param `denominator` MUST be either exactly 1, or evenly divisible by 10.
     */
    function uintToString(uint value, uint denominator) internal pure returns (string memory str) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (denominator % 10 > 0) {
            denominator -= denominator % 10;
        }

        if (denominator == 0) {
            denominator = 1;
        }

        // String containing whole numbers only.
        str = _uintToString(value / denominator);

        if (denominator > 9) {
            uint decimalToShow;

            // Let's generate a nice, clear error message with the proper decimals.
            // We need to use assembly to achieve a proper, non-overflowing modulo.
            assembly { decimalToShow := mod(value, denominator) }

            // Now generate the decimals string, fixed to the number of global `decimals`.
            string memory strDecimals = _uintToString(decimalToShow);

            if (decimalToShow > 0) {
                for (; decimalToShow < denominator / 10; decimalToShow *= 10) {
                    strDecimals = string.concat("0", strDecimals);
                }
            }

            // Lastly, assemble the string.
            str = string.concat(str, ".", strDecimals);
        }
        return str;
    }

    function intToString(int value) internal pure returns (string memory) {
        return intToString(value, 1);
    }

    function intToString(int value, uint denominator) internal pure returns (string memory) {
        if (value < 0) {
            // Convert the `value` negative and signed integer to a positive
            // uint by multiplying it by -1. Affix the negative signer "-" string
            // designation as its suffix upon return.
            return string.concat("-", uintToString(uint(-1 * value), denominator));
        }
        return uintToString(uint(value), denominator);
    }

This lets you convert either uint256 or int256 to a string in Solidity 0.8.x. If you're using a smaller memory value such as uint8, you might need to cast it prior to invocation like so: uintToString(uint(myUint8Variable)) --> string memory.

Also provided are overloaded functions such that inside Solidity you may use whichever is most convenient: Either include an explicit denominator to print 1.151100 USDC or omit the denominator to print the unadulterated number such as 1151100 USDC.

The four functions with an internal visibility are intended for access. The _uintToString() function should not be explicitly used unless you desire to restructure the system. The internal visibility permits you to put them in a Library and link them across an entire smart contract ecosystem like I've done at Triple Confirmation.

Hope this helps! Cheers

intToString() correctly parses negative integers

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.