C++14无符号整数溢出的进一步理解
Further understanding of unsigned integer overflow in C++14
为什么 following code 对于 uint8_t
的情况会失败?
#include <iostream>
#include <cstdint>
#include <stack>
template <typename TT>
void PrintNumberScientificNotation (TT number) {
constexpr TT kBase{10}; // Base of the numerical system.
TT xx{number}; // Number to convert.
TT exponent{}; // Exponent.
std::stack<TT> fractional_part{}; // Values in the fractional part.
do {
fractional_part.push(xx%kBase);
xx /= kBase;
exponent++;
} while (xx > kBase);
std::cout << xx << '.';
while (!fractional_part.empty()) {
std::cout << fractional_part.top();
fractional_part.pop();
}
std::cout << " x 10^" << exponent << std::endl;
}
int main () {
uint8_t number_1{255};
PrintNumberScientificNotation(number_1); // Does not work.
uint16_t number_2{255};
PrintNumberScientificNotation(number_2); // Works.
uint16_t number_3{65'535};
PrintNumberScientificNotation(number_3); // Works.
uint32_t number_4{4'294'967'295};
PrintNumberScientificNotation(number_4); // Works.
uint64_t number_5{18'446'744'073'709'551'615};
PrintNumberScientificNotation(number_5); // Works.
}
输出:
. x 10^
2.55 x 10^2
6.5535 x 10^4
4.294967295 x 10^9
1.8446744073709551615 x 10^19
据我了解,uint8_t
能够表示不超过 255 的无符号整数 (UINT8_MAX
)。为什么我可以代表所有其他表示的最大值?
uint8_t 被视为字符,因此它将使用 ASCII 代码打印字符。在打印之前,您必须将 uint8_t 值转换为无符号值,如下所示:
uint8_t number_1{255};
PrintNumberScientificNotation(unsigned(number_1));
您的代码的数学部分没问题,打印有问题。
如果您使用 cout
代替 uint_t
,它会将 uint_t
解释为字符代码。那是因为 uint_t
是 unsigned char 的类型别名。
一个可能的解决方法是显式转换为整数:
std::cout << unsigned(xx) << '.';
while (!fractional_part.empty()) {
std::cout << unsigned(fractional_part.top());
fractional_part.pop();
}
std::cout << " x 10^" << unsigned(exponent) << std::endl;
为什么 following code 对于 uint8_t
的情况会失败?
#include <iostream>
#include <cstdint>
#include <stack>
template <typename TT>
void PrintNumberScientificNotation (TT number) {
constexpr TT kBase{10}; // Base of the numerical system.
TT xx{number}; // Number to convert.
TT exponent{}; // Exponent.
std::stack<TT> fractional_part{}; // Values in the fractional part.
do {
fractional_part.push(xx%kBase);
xx /= kBase;
exponent++;
} while (xx > kBase);
std::cout << xx << '.';
while (!fractional_part.empty()) {
std::cout << fractional_part.top();
fractional_part.pop();
}
std::cout << " x 10^" << exponent << std::endl;
}
int main () {
uint8_t number_1{255};
PrintNumberScientificNotation(number_1); // Does not work.
uint16_t number_2{255};
PrintNumberScientificNotation(number_2); // Works.
uint16_t number_3{65'535};
PrintNumberScientificNotation(number_3); // Works.
uint32_t number_4{4'294'967'295};
PrintNumberScientificNotation(number_4); // Works.
uint64_t number_5{18'446'744'073'709'551'615};
PrintNumberScientificNotation(number_5); // Works.
}
输出:
. x 10^
2.55 x 10^2
6.5535 x 10^4
4.294967295 x 10^9
1.8446744073709551615 x 10^19
据我了解,uint8_t
能够表示不超过 255 的无符号整数 (UINT8_MAX
)。为什么我可以代表所有其他表示的最大值?
uint8_t 被视为字符,因此它将使用 ASCII 代码打印字符。在打印之前,您必须将 uint8_t 值转换为无符号值,如下所示:
uint8_t number_1{255};
PrintNumberScientificNotation(unsigned(number_1));
您的代码的数学部分没问题,打印有问题。
如果您使用 cout
代替 uint_t
,它会将 uint_t
解释为字符代码。那是因为 uint_t
是 unsigned char 的类型别名。
一个可能的解决方法是显式转换为整数:
std::cout << unsigned(xx) << '.';
while (!fractional_part.empty()) {
std::cout << unsigned(fractional_part.top());
fractional_part.pop();
}
std::cout << " x 10^" << unsigned(exponent) << std::endl;