Chapter 6.3 "Know an Algorithm's Complexity" of the book Real-Time C++包含以下列表:
std::uint16_t a = UINT16_C(55555);
std::uint16_t b = UINT16_C(61234);
void do_something()
{
// Unsigned 16 x 16 --> 32-bit = 3,401,854,870.
std::uint32_t result = a * static_cast<std::uint32_t>(b);
}
在文中,作者指出,最好只将乘法的一个操作数转换为 std::uint32_t
,因为这样编译器可能会“在 16 x 16 - 中较好的一个之间进行选择” -> 32 位乘法和 32 x 32 --> 32 位乘法,仍然得到正确的答案”,具体取决于 CPU 架构(例如 8 位或 32 位)。
我不明白编译器如何执行 16 x 16 --> 32 位乘法,因为操作数 b
被显式转换为 std::uint32_t
。如果我正确理解整数提升/转换规则,操作数 a
将在乘法之前提升为 std::uint32_t
并且编译器只能执行 32 x 32 --> 32 位乘法。
我在这里遗漏了什么吗?
最佳答案
C++ 标准仅指定程序的可观察行为 [intro.execution:1]:
Rather, conforming implementations are required to emulate (only) the observable behavior of the abstract machine as explained below.
因为您没有观察 static_cast<std::uint32_t>(b)
的结果,符合标准的编译器没有义务实际计算这个子表达式。只需要执行乘法就好像其中一个操作数是 32 位(因此结果不是 16 位,这是这里唯一可观察到的含义)。
关于c++ - 让编译器根据架构选择乘法算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34569900/