java - 为什么这个 Szudzik Elegant Pairing 给出了错误的结果?

标签 java algorithm function math equation

我使用优雅的配对方式将两个数字配对形成一个唯一的数字。但是,当我将两个相同的数字配对到 67108863 以上时,例如“pair(67108864,67108864)”,它会给我 4503599761588224。当我想取消配对时,它会给我 (-1,67108865)。然后我尝试配对(-1,67108865),它也给了我4503599761588224。所有其他不同的数字在 67108864 下给出唯一的数字或相同的数字,我可以对它们进行配对和取消配对,除非我在 67108863 上配对相同的数字; (67108864,67108864),(507108864,507108864)等

我的代码是否有错误,或者我刚刚发现 Szudzik 优雅配对功能存在问题?

/**
 *
 * @author HiltherJoe
 */
public class ElegantP {
    public static long pair(long x, long y) {
        return x >= y ? x * x + x + y : y * y + x;
    }
    public static long[] unpair(long z) {
        long b = (long) Math.sqrt(z);
        long a = z - b * b;
        return a < b ? new long[]{a, b} : new long[]{b, a - b};
    }
    public static void main(String[] args){
        int i = 67108864;
        long pairedNumber = pair(i, i);
        long[] unpair = unpair(pairedNumber);
        System.out.println("Paired Number is    " + pairedNumber);
        System.out.println("First unpaired Number is    " + unpair[0]+"    Second unpaired Number is    "+unpair[1]);
    }
}

最佳答案

此代码使用 Math.sqrt() double计算 - 结果不够精确。对于 4503599761588224 ( pair(67108864,67108864) ),结果是 67108865而不是67108864 .

使用BigInteger.sqrt() (或任何其他精确方法)并且它应该有效:

long b = BigInteger.valueOf(z).sqrt().longValue();
long a = z - b * b;

对于更大的数字,仍然存在溢出风险,如 commented通过 SMA

关于java - 为什么这个 Szudzik Elegant Pairing 给出了错误的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59035146/

相关文章:

function -::(双冒号)代表什么?

java - 域模型模式示例

java - 图书馆计划 - 分配和借阅书籍

algorithm - 使用 Maximum Flow 为人们分配工作,更难的版本

python-3.x - 如果子字符串包含在列表中,则从字符串中删除子字符串

javascript - 性能:为什么相同算法的第一个实现明显更快

java - 找不到我的 file.properties

java - 异常线程 "main"org.springframework.beans.factory.BeanDefinitionStoreException 当我在做一个示例项目时

c - 通过函数中的指针修改结构成员

mysql - 使用MySql函数变量作为查询中的表名