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?
2 Answers
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
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