不使用除法或强制转换将整数除以 16

发布于 2024-10-09 20:51:13 字数 76 浏览 4 评论 0原文

好吧...让我重新表述一下这个问题...

如何在不使用除法或转换为 double 的情况下获得整数的 x 16ths...

OKAY... let me rephrase this question...

How can I obtain x 16ths of an integer without using division or casting to double....

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

你好,陌生人 2024-10-16 20:51:13
int res = (ref * frac) >> 4

(但是有点担心溢出。 ref 和 frac 能得到多大?如果可能溢出,首先转换为更长的整数类型)

int res = (ref * frac) >> 4

(but worry a a bit about overflow. How big can ref and frac get? If it could overflow, cast to a longer integer type first)

坠似风落 2024-10-16 20:51:13

在任何此类运算中,先乘后除是有意义的。现在,如果您的操作数是整数并且您使用的是可编译语言(例如 C),请使用 shr 4 而不是 /16 - 这将节省一些处理器周期。

In any operation of such kind it makes sense to multiply first, then divide. Now, if your operands are integers and you are using a compileable language (eg. C), use shr 4 instead of /16 - this will save some processor cycles.

方圜几里 2024-10-16 20:51:13

假设这里的所有内容都是整数,任何有价值的优化编译器都会注意到 16 是 2 的幂,并相应地移动 frac —— 只要优化打开。更多地担心编译器无法为您完成的主要优化。

如果有的话,您应该将 ref * frac 括起来,然后进行除法,因为任何小于 16 的 frac 值都将得到 0,无论是通过移位还是除法。

Assuming everything here are ints, any optimizing compiler worth its salt will notice 16 is a power of two, and shift frac accordingly -- so long as optimizations are turned on. Worry more about major optimizations the compiler can't do for you.

If anything, you should bracket ref * frac and then have the divide, as any value of frac less than 16 will result in 0, whether by shift or divide.

调妓 2024-10-16 20:51:13

您可以使用左移或右移:

public static final long divisionUsingMultiplication(int a, int b) {
    int temp = b;
    int counter = 0;
    while (temp <= a) {
        temp = temp<<1;
        counter++;
    }
    a -= b<<(counter-1);
    long result = (long)Math.pow(2, counter-1);
    if (b <= a) result += divisionUsingMultiplication(a,b);
    return result;
}

public static final long divisionUsingShift(int a, int b) {
    int absA = Math.abs(a);
    int absB = Math.abs(b);
    int x, y, counter;

    long result = 0L;
    while (absA >= absB) {
        x = absA >> 1;
        y = absB;
        counter = 1;
        while (x >= y) {
            y <<= 1;
            counter <<= 1;
        }
        absA -= y;
        result += counter;
    }
    return (a>0&&b>0 || a<0&&b<0)?result:-result;
}

You can use left shift or right shift:

public static final long divisionUsingMultiplication(int a, int b) {
    int temp = b;
    int counter = 0;
    while (temp <= a) {
        temp = temp<<1;
        counter++;
    }
    a -= b<<(counter-1);
    long result = (long)Math.pow(2, counter-1);
    if (b <= a) result += divisionUsingMultiplication(a,b);
    return result;
}

public static final long divisionUsingShift(int a, int b) {
    int absA = Math.abs(a);
    int absB = Math.abs(b);
    int x, y, counter;

    long result = 0L;
    while (absA >= absB) {
        x = absA >> 1;
        y = absB;
        counter = 1;
        while (x >= y) {
            y <<= 1;
            counter <<= 1;
        }
        absA -= y;
        result += counter;
    }
    return (a>0&&b>0 || a<0&&b<0)?result:-result;
}
日裸衫吸 2024-10-16 20:51:13

我不明白这个约束,但是这个伪代码四舍五入(?):

res = 0
ref= 10
frac = 2
denominator = 16
temp = frac * ref
while temp > 0
   temp -= denominator
   res += 1
repeat
echo res

I don't understand the constraint, but this pseudo code rounds up (?):

res = 0
ref= 10
frac = 2
denominator = 16
temp = frac * ref
while temp > 0
   temp -= denominator
   res += 1
repeat
echo res
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文