Formatting Support
Boost.int128 support formatting with both <format> (when C++20 and the header are both available), and <fmt/format.h>
The following modifiers are listed in order of how they should be specified in the format string to be valid, and all information applies for both <format> and <fmt/format.h>
Fill and Alignment
You can specify alignment with an optional fill character. The format is [[fill]align] where:
Alignment |
Effect |
|
Left-aligns the value within the available space |
|
Right-aligns the value within the available space |
|
Centers the value within the available space |
The optional fill character (default is space) appears before the alignment character.
Examples:
Format |
Output for 42 |
|
|
|
|
|
|
|
|
|
|
|
|
When no alignment is specified but a width is given (e.g., {:6d}), zero-padding is applied from the left.
|
Sign
There are three allowable sings first in the format string:
Sign |
Effect |
|
Adds a |
|
Only adds a |
` ` (Space) |
Adds a ` ` to positive values, and a |
Padding
You can then add any number of padding characters to make sure that a formatted value takes up a specified width (5 means minimum width of 5 characters and so on). Any integer value is accepted here.
Prepend Prefix
If you want to prepend the prefix to your number (if applicable) add #
Output Base |
Effect |
Binary |
|
Octal |
|
Decimal |
None |
Hex |
|
Output Base Modifiers
The following type modifiers are the same as those used by built-in integer values
Modifier |
Format |
b, B |
Binary |
o |
Octal |
d |
Decimal |
x, X |
Hex |
| When the uppercase modifier is used all characters will be capitalized (e.g. 0x2a vs 0X2A) |
Default
The default format string {} will output the same as {:-d}, that is a decimal value which only has a sign if negative.
<format>
Examples using all of the above modifiers in some permutation:
#include <boost/int128.hpp>
#include <format>
#include <iostream>
int main()
{
constexpr boost::int128::int128_t value {42};
// Default format
std::cout << std::format("{}", value) << '\n'; // Outputs: 42
// Sign modifier
std::cout << std::format("{:+d}", value) << '\n'; // Outputs +42
std::cout << std::format("{:+d}", -value) << '\n'; // Outputs -42
// Alignment with fill characters
std::cout << std::format("{:<10d}", value) << '\n'; // Outputs "42 " (left-aligned)
std::cout << std::format("{:>10d}", value) << '\n'; // Outputs " 42" (right-aligned)
std::cout << std::format("{:^10d}", value) << '\n'; // Outputs " 42 " (centered)
std::cout << std::format("{:*<10d}", value) << '\n'; // Outputs "42********" (left, fill with *)
std::cout << std::format("{:0>10d}", value) << '\n'; // Outputs "0000000042" (right, fill with 0)
std::cout << std::format("{:*^10d}", value) << '\n'; // Outputs "****42****" (centered, fill with *)
// Alignment with sign
std::cout << std::format("{:>+10d}", value) << '\n'; // Outputs " +42"
std::cout << std::format("{:<+10d}", value) << '\n'; // Outputs "+42 "
// Output base modifier and Prefix
std::cout << std::format("{:x}", value) << '\n'; // Outputs 2a
std::cout << std::format("{:X}", value) << '\n'; // Outputs 2A
std::cout << std::format("{:#X}", value) << '\n'; // Outputs 0X2A
// Alignment with hex and prefix
std::cout << std::format("{:>#10x}", value) << '\n'; // Outputs " 0x2a"
std::cout << std::format("{:<#10x}", value) << '\n'; // Outputs "0x2a "
std::cout << std::format("{:*^#10x}", value) << '\n'; // Outputs "***0x2a***"
// Zero-padding (no alignment specified)
std::cout << std::format("{:#10X}", value) << '\n'; // Outputs 0X00000002A
return 0;
}
{fmt}
This is nearly the same as above but with fmt::format in place of std::format:
#include <boost/int128.hpp>
#include <fmt/format.h>
#include <iostream>
int main()
{
constexpr boost::int128::int128_t value {42};
// Default format
std::cout << fmt::format("{}", value) << '\n'; // Outputs: 42
// Sign modifier
std::cout << fmt::format("{:+d}", value) << '\n'; // Outputs +42
std::cout << fmt::format("{:+d}", -value) << '\n'; // Outputs -42
// Alignment with fill characters
std::cout << fmt::format("{:<10d}", value) << '\n'; // Outputs "42 " (left-aligned)
std::cout << fmt::format("{:>10d}", value) << '\n'; // Outputs " 42" (right-aligned)
std::cout << fmt::format("{:^10d}", value) << '\n'; // Outputs " 42 " (centered)
std::cout << fmt::format("{:*<10d}", value) << '\n'; // Outputs "42********" (left, fill with *)
std::cout << fmt::format("{:0>10d}", value) << '\n'; // Outputs "0000000042" (right, fill with 0)
std::cout << fmt::format("{:*^10d}", value) << '\n'; // Outputs "****42****" (centered, fill with *)
// Alignment with sign
std::cout << fmt::format("{:>+10d}", value) << '\n'; // Outputs " +42"
std::cout << fmt::format("{:<+10d}", value) << '\n'; // Outputs "+42 "
// Output base modifier and Prefix
std::cout << fmt::format("{:x}", value) << '\n'; // Outputs 2a
std::cout << fmt::format("{:X}", value) << '\n'; // Outputs 2A
std::cout << fmt::format("{:#X}", value) << '\n'; // Outputs 0X2A
// Alignment with hex and prefix
std::cout << fmt::format("{:>#10x}", value) << '\n'; // Outputs " 0x2a"
std::cout << fmt::format("{:<#10x}", value) << '\n'; // Outputs "0x2a "
std::cout << fmt::format("{:*^#10x}", value) << '\n'; // Outputs "***0x2a***"
// Zero-padding (no alignment specified)
std::cout << fmt::format("{:#10X}", value) << '\n'; // Outputs 0X00000002A
return 0;
}