English 中文(简体)
这一多功能是否正确?
原标题:Is this multiply-divide function correct?

I m trying to avoid long longs and integer overflow in some calculations, so I came up with the function below to calculate (a * b) / c (order is important due to truncating integer division).

 unsigned muldiv(unsigned a, unsigned b, unsigned c)
 {
      return a * (b / c) + (a * (b % c)) / c;
 }

是否有任何最优的案例,这些案例会像预期的那样赢得工作?

最佳回答

EDITED: This is correct for a superset of values for which the original obvious logic was correct. It still buys you nothing if c > b and possibly in other conditions. Perhaps you know something about your values of c but this may not help as much as you expect. Some combinations of a, b, c will still overflow.

EDIT:由于严格的C++98便携式原因,假设你重新避免<条码>长期,你可以通过促进<条码>至<条码>的<>unsign至<条码>,从而获得大约52个精度参数,这些参数很可能具有完成数学的整体价值。 事实上,使用<条码>杜布尔的数学可能比三个整体司要快。

问题回答

这在几个案件中是失败的。 最为明显的是,<代码>a是大型的,因此a * (b % c) 超支。 在此情况下,你可以尝试打字<条码>a和<条码>b,但如<条码>、<条码>、<条码>、<条码>和<条码>仍为之。 审议a =b = 2^25-1 and c = 2^24 with a 32 bit unsign. 正确结果为2^26-4,但a * (b % c)b* (a % c)均将超支。 甚至<代码>(c %) * (b % c)也会流出。

迄今为止,解决这一问题的总体最突出的途径是扩大倍数,使中间产品更加精确。 如果你没有这样做的话,你需要将其综合起来,摆脱较小的多层次和分裂,这在很大程度上与执行你自己的大面积图书馆相同。

如果你可以认为<条码>c小到<条码>(c-1)*(c-1)不会溢出未签名,你可以使用:

unsigned muldiv(unsigned a, unsigned b, unsigned c) {
    return (a/c)*(b/c)*c + (a%c)*(b/c) + (a/c)*(b%c) + (a%c)*(b%c)/c;
}

这实际上将给你所有a和b的“正确”答案——a * b)/c %(UINT_max+1)

To avoid overflow you have to pre-divide and then post-multiply by some factor.

最佳使用系数为c,只要(或两者)大于c。 这就是Chris Dodd的职能。 它的中间体最大((c % c) * (b % c)),正如Chris指出的,中间体小于或等于(c-1)*(c-1)。

If you could have a situation where both a and b are less than c, but (a * b) could still overflow, (which might be the case when c approaches the limit of the word size) then the best factor to use is a large power of two, to turn the multiply and divides into shifts. Try shifting by half the word size.

请注意,如果你没有更长的字句,则使用预告器,然后使用多面字。 假设你不要抛弃低秩序轨道,而只是将其作为另一个术语,那么你只是使用几个字而不是一个大字。

我恳请你填写该守则。





相关问题
How to add/merge several Big O s into one

If I have an algorithm which is comprised of (let s say) three sub-algorithms, all with different O() characteristics, e.g.: algorithm A: O(n) algorithm B: O(log(n)) algorithm C: O(n log(n)) How do ...

Grokking Timsort

There s a (relatively) new sort on the block called Timsort. It s been used as Python s list.sort, and is now going to be the new Array.sort in Java 7. There s some documentation and a tiny Wikipedia ...

Manually implementing high performance algorithms in .NET

As a learning experience I recently tried implementing Quicksort with 3 way partitioning in C#. Apart from needing to add an extra range check on the left/right variables before the recursive call, ...

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

Enumerating All Minimal Directed Cycles Of A Directed Graph

I have a directed graph and my problem is to enumerate all the minimal (cycles that cannot be constructed as the union of other cycles) directed cycles of this graph. This is different from what the ...

Quick padding of a string in Delphi

I was trying to speed up a certain routine in an application, and my profiler, AQTime, identified one method in particular as a bottleneck. The method has been with us for years, and is part of a "...

热门标签