Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 确定点的象限_Java_Performance_Geometry - Fatal编程技术网

Java 确定点的象限

Java 确定点的象限,java,performance,geometry,Java,Performance,Geometry,我需要以更快的方式确定点的象限。我只知道“使用符号确定”方法。我正在寻找一个好的方法,如果有的话。如果不是的话,对我的代码进行任何修复都会有所帮助。假设平面上有4个四边形。我的代码- int x = scan.nextInt() > 0 ? 1 : 0; int y = scan.nextInt() > 0 ? 1 : 0; switch (x) { case 1: switch (y) {

我需要以更快的方式确定点的象限。我只知道“使用符号确定”方法。我正在寻找一个好的方法,如果有的话。如果不是的话,对我的代码进行任何修复都会有所帮助。假设平面上有4个四边形。我的代码-

        int x = scan.nextInt() > 0 ? 1 : 0;
        int y = scan.nextInt() > 0 ? 1 : 0;
        switch (x) {
        case 1:
            switch (y) {
            case 1:
                quad = 1;
                break;
            case 0:
                quad = 4;
                break;
            }
            break;

        case 0:
            switch (y) {
            case 1:
                quad = 2;
                break;
            case 0:
                quad = 3;
                break;
            }
            break;
        }

这是给你的方法。看起来很简单

getQuadrant(int x, int y) {
    if (x >= 0) {
        return y >= 0 ? 1 : 4;
    } else {
        return y >= 0 ? 2 : 3;
    }
}

分支和内存查找是对代码片段进行微优化时要避免的事情。使用内联汇编,您只需使用CMOV(条件MOV)即可在x86系统上获得加速。Java的hotspot编译器也可以使用此指令。但是由于代码段非常简单,为了避免分支或内存查找而执行太多操作可能(最终)是失败的

static int[] QUAD_LUT = new int[]{1, 2, 4, 3};
...
// use the sign bit on the integers
return QUAD_LUT[ (x >>> 31) | ((y >>> 30) & 0x2) ]
当你想到你追求的结果时

x.sign y.sign Quad
0      0      1
0      1      4
1      0      2
1      1      3
您可以使用公式

(x.sign XOR y.sign + y.sign + y.sign) + 1
y = (y>>>31);
return ((x>>>31) ^ y) + y + y + 1;
因此在Java中

(x.sign XOR y.sign + y.sign + y.sign) + 1
y = (y>>>31);
return ((x>>>31) ^ y) + y + y + 1;
编辑仅适用于对内联装配感兴趣的人

;; NASM/FASM syntax
;; GetQuadrant(int x, int y)
;; RETURN [1|2|3|4] in EAX register
GetQuadrant:
    MOV     eax, [esp+4] ;; = x
    MOV     ecx, [esp+8] ;; = y
    SHR     eax, 31 ;; = >> 31
    SHR     ecx, 31 ;; = >> 31 
    XOR     eax, ecx ;; = x XOR y
    LEA     eax, [eax + ecx * 2 + 1] ;; = x + y*2 + 1
    RET     8 ;; correct stack and return

保持简单!不需要分支、位旋转、内存查找、汇编语言或其他复杂操作

int getQuadrant(int x, int y) {
    int X = (x >= 0);
    int Y = (y >= 0);
    return 3 + X - Y - 2 * X * Y;
}
(说明。如在我的函数中给出的
X
Y
,象限由以下二次多项式给出:

1 * X * Y  +  2 * (1 - X) * Y  +  3 * (1 - X) * (1 - Y)  +  4 * X * (1 - Y)

然后,如果你收集术语并进行简化,你就会得到我使用的表达式。)

我真的很喜欢上面的比特旋转示例-但我需要在3d和C中使用它。。。所以,以防万一,这是有用的。我相信,如果有人需要,这已经足够接近于转换成java了

int
point_to_3d_quad (int x, int y, int z)
{
    static int q[] = { 1, 2, 3, 4, 5, 6, 7, 8 };

    int X = (x >> ((sizeof(x)*8)-1)) & 1;
    int Y = ((y >> ((sizeof(y)*8)-1)) & 1) << 1;
    int Z = ((z >> ((sizeof(z)*8)-1)) & 1) << 2;

    return (q[X | Y | Z]);
}
int
点到三维四元(整数x,整数y,整数z)
{
静态int q[]={1,2,3,4,5,6,7,8};
intx=(X>>(sizeof(X)*8)-1))&1;

int Y=((Y>>((sizeof(Y)*8)-1))&1>((sizeof(z)*8)-1))&1)这是家庭作业吗?您是否实现了“使用符号确定”算法?它是否存在性能问题(为什么不够快?)。向我们展示您的代码。@Jesper不是作业。粘贴了我的代码。好吧,那为什么它不够快?我正在寻找一种更快的方法。只要告诉我是否有。它确实比我的方法简单。但不是更快。如果目标是性能,那么这个答案是不正确的。分支是已知的性能障碍。如果目标是最佳实践/清晰性,则不是他是一个明显的赢家。很好,祝贺你!很好。我没有想到这些运算符。从性能上看,这是使用2个分支和内存查找。使用带有静态“quads”查找的无分支版本可能会使其成为优化的一般选择。这不是JAVA。我无法初始化int X=(X>=0);因为表达式返回一个布尔值。啊,好吧。我认为这类东西显示了与单独的布尔类型相比的优势。