以下 C++ 代码用于 -> "#define idiv(a, b) (((a) + (b) / 2) / (b))" 是什么?

What is the following C++ code used for -> "#define idiv(a, b) (((a) + (b) / 2) / (b))"?

本文关键字:是什么 idiv 用于 代码 C++ #define gt 以下      更新时间:2023-10-16

我正在使用经常使用一些重要优化的代码。 什么是

#define idiv(a, b) (((a) + (b) / 2) / (b))

用于?为什么不简单地

#define idiv(a, b) ((a)/(b) + 0.5)

是整数除法溢出保护还是别的什么?

整数除法截断为零。假设(从宏的名称,idiv(你的参数是整数类型,((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;
}

仍然,此代码没有达到作者的预期。计划是将结果舍入到最接近的整数值,但如果一个参数具有负值,则失败。

请参阅此内容并注意失败a: 4 b: -2

并且还有整数溢出问题(请参阅最后一个测试用例(。