【问题标题】:CEIL is one too high for exact integer divisionsCEIL 对于精确的整数除法来说太高了
【发布时间】:2012-10-18 03:18:19
【问题描述】:

今天早上我丢失了一堆文件,但是由于它们所在的卷在内部和外部都进行了碎片整理,因此可以获得 100% 恢复所需的所有信息;我只需要在需要的地方填写 FAT。

我编写了一个程序来执行此操作,并在我转储到文件的 FAT 副本上对其进行了测试,它运行良好,除了少数文件(526 个文件中的 17 个),FAT 链是一个单一的簇太长,因此与下一个文件交叉链接。

幸运的是,我确切地知道问题出在哪里。我在 EOF 计算中使用了ceil,因为即使超过一个字节也需要一个额外的集群:

//Cluster    is the starting cluster of the file
//Size       is the size (in bytes) of the file
//BPC        is the number of bytes per cluster
//NumClust   is the number of clusters in the file
//EOF        is the last cluster of the file’s FAT chain

DWORD NumClust = ceil( (float)(Size / BPC) )
DWORD EOF      = Cluster + NumClust;

此算法适用于所有文件,但大小恰好是集群大小的倍数的文件除外,在这种情况下,它们最终成为一个集群太多了。

我想了一会儿,但不知如何做到这一点。看起来应该很简单,但不知何故却出人意料地棘手。

什么公式适用于任何大小的文件?

【问题讨论】:

  • 一开始为什么要把它转换成float???
  • @HotLicks,因为没有它,我会收到错误 ambiguous call to ceil…
  • 为什么你觉得有必要使用ceil?理论上,一个 int 的 ceil 应该总是返回相同的 int。
  • @HotLicks,即使超过一个字节也意味着一个额外的集群,所以它总是必须四舍五入;因此ceil。我认为这在逻辑上比尝试并依赖整数除法和隐含舍入更清晰。
  • 整数除法比依赖于整数到浮点数的随机转换要可靠得多。如果你真的想使用 ceil 你需要做浮点除法,或者它基本上是一个空操作。

标签: c++ formula ceil off-by-one


【解决方案1】:

如果您想要集群的数量,它会是 (size + BPC - 1) / BPC,包含所有整数数据类型。

【讨论】:

    【解决方案2】:

    也许是ceil( (float)((Size - 1) / BPC) )

    如果一切都是整数类型,那就更好了((Size - 1) / BPC) + 1

    【讨论】:

    • 嗯,这很奇怪。我认为从大小中减去一个最终会产生不同的边缘情况错误,但我尝试了它并且它起作用了。 ಠ_ಠ 我只能假设这是因为我碰巧没有任何大小适合该特定边缘情况的文件。不管怎样,它奏效了。非常感谢。
    【解决方案3】:

    ceil( (float)(Size / BPC) ) 进行整数除法,然后将其转换为浮点数。

    您需要ceil( (float)Size / BPC ) 才能正确执行此操作。但是首先在这里使用浮点数似乎不是一个好主意......请参阅整数解决方案的其他答案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多