该代码中 std::max 用法的解释?

Explanation of the usage of std::max in that code?

我不确定我是否应该在 codereview.stackexchange.com 上发布这个问题。不管怎样,我们开始吧...

请考虑以下代码片段,它是从 here 中摘录的文字(我只是更改了格式),并且已在德国计算机杂志 c' 中打印(以精简形式), 23/2019 期:

while (lo <= hi) {
  std::streamoff pos = std::streamoff((uint64_t(lo) + uint64_t(hi)) / 2);
  pos -= pos % std::streamoff(PasswordHashAndCount::size);
  pos = std::max<int64_t>(0, pos);
  phc.read(mInputFile, pos);
  ++nReads;
  if (hash > phc.hash) {
    lo = pos + std::streamoff(PasswordHashAndCount::size);
  }
  else if (hash < phc.hash) {
    hi = pos - std::streamoff(PasswordHashAndCount::size);
  }
  else {
    safe_assign(readCount, nReads);
    return phc;
  } 
}

为什么我们需要第四行pos = std::max<int64_t>(0, pos);

从第二行,我们看到 pos 等于或大于 0,因为它是两个本身属于 uint64_t 类型的数之和的一半.

第三行不能使pos低于0。证明:

为简单起见,将 pos 替换为 A,将 std::streamoff(PasswordHashAndCount::size) 替换为 B。然后第三行是A -= A % B,相当于A = A - (A % B),其中AB是整数,A等于或大于0,并且 B 大于 0(因为 ::size 总是大于 0)。

首先,如果A < BA % B = A。这样的话,第三行就变成了A = A - A,即A = 0.

其次,如果A == BA % B变为A % A,即0。所以,第三行就变成了A = A - 0,相当于空操作。换句话说, A 在那种情况下不会改变;值得注意的是,它仍然是 0 或更大。

第三,如果A > BA - (A % B)大于0。这是因为 A % B 小于 B,因此 A - (A % B) 大于 A - B。后者又大于0,因为这里的条件是A > B.

当然,A > BA < BA == B这三种情况都是可能发生的情况。在每种情况下,第三行都会为 A 分配一个新值,即 0 或正数。

回到原来的变量命名,这意味着pos在第三行执行后总是0或大于

鉴于此,我不明白第四行的作用。毕竟,如果 pos0 或正数,max(0, pos) 总是等同于 pos

我错过了什么?以上推理有没有错误?

让我们考虑一下它到底做了什么:

std::streamoff pos = std::streamoff((uint64_t(lo) + uint64_t(hi)) / 2);
pos = std::max<int64_t>(0, pos);

std::streamoff 是一些实现定义的有符号整数类型。让我们考虑一个 64 位或更小的类型的情况: pos 的值不会因转换为 int64_t 而改变,因为类型更宽,在赋值中转换回来时也不会改变,因为原始值必须是可表示的。

让我们考虑一种情况,其中 std::streamoff 是 128 位或更宽的类型:值来自 (uint64_t(lo) + uint64_t(hi)) / 2,不能超过最大值 int64_t。因此,在这种情况下,该值也无法通过转换更改。

因此,使用int64_t在任何情况下都没有效果。

The third line can't make pow lower than 0

Is there an error in the reasoning above?

我找不到任何错误。

Given that, I don't understand what the fourth line does.

该行对程序的行为完全没有影响。如果该行写成:

,程序将具有相同的行为
;

此外,在您在台式机或服务器上找到的大多数系统上,std::streamoffint64_t 具有相同的位数。