我正在处理经常使用一些重要优化的代码。是什么
#define idiv(a, b) (((a) + (b) / 2) / (b))
Run Code Online (Sandbox Code Playgroud)
用于?为什么不简单
#define idiv(a, b) ((a)/(b) + 0.5)
Run Code Online (Sandbox Code Playgroud)
是整数除法溢出保护还是其他什么?
整数除法向零截断。假设(从宏的名称,i div)您的参数是整数类型,((a)/(b) + 0.5)将在您到达之前被截断+ 0.5,因此无论如何您总是会向下舍入。
(((a) + (b) / 2) / (b))发了结果大于X.5,不使用浮点运算。
注意:您标记了您的问题 C++。在 C++ 中,你不应该“宏”任何东西,真的。检查 Marek 对模板解决方案的回答(但也要注意它实际上不适用于负值)。
您建议的修改并不等效,因为a/b参数为整数时是整数除法。您应该首先将参数转换为浮点数。
第一个宏避免转换为浮点,这可能会更快。此外,将值转换为浮点数再转换回整数可能会失去精度,因为并非所有整数都可以精确地表示为浮点数。
这段代码是C宏,在 C++ 中被认为是一种非常糟糕的做法。在 C++ 中,您应该使用模板(有人说这是更智能的宏)。
template<typename T>
constexpr T idiv(T a, T b) {
return (a + b / 2) / b;
}
Run Code Online (Sandbox Code Playgroud)
这段代码仍然没有达到作者的预期。计划是将结果四舍五入到最接近的整数值,但如果一个参数为负值,则失败。
看到这个并注意失败a: 4 b: -2
还有整数溢出问题(见最后一个测试用例)。