用Java重写的JavaScript函数产生不同的结果


9

我正在尝试用Java重写以下Javascript函数:

function normalizeHash(encondindRound2) {
    if (encondindRound2 < 0) {
        encondindRound2 = (encondindRound2 & 0x7fffffff) + 0x80000000;
    }
    return encondindRound2 % 1E6;
}

我的Java适应:

public long normalizeHash(long encondindRound2) {
        if (encondindRound2 < 0) {
            encondindRound2 = (((int) encondindRound2) & 0x7fffffff) + 0x80000000;
        }
        return (((int) encondindRound2) % 1_000_000);
    }

当我通过时-1954896768,Javascript版本返回70528,而Java返回-896768。我不知道为什么。区别似乎始于if条件:在if后面的Javascript函数中encodingRound2 = 2340070528,而在Java:中encodingRound2 = -1954896768

我做了这些代表以在线显示它:

Javascripthttps : //repl.it/repls/NumbGuiltyHack

Javahttps//repl.it/repls/ClumsyQualifiedProblem

编辑:更改Java函数为此

public long normalizeHash(long encondindRound2) {
        if (encondindRound2 < 0) {
            encondindRound2 = (encondindRound2 & 0x7fffffff) + 0x80000000;
        }
        return (encondindRound2 % 1_000_000);
    }

似乎并不影响结果-仍然 -896768


1
为什么encondindRound2int在Java代码中强制转换为?由于将其定义为long,如果将其强制转换为较窄的类型,则可能会失去精度。
约旦

1
@Jordan,因为-在if中-正在进行按位操作。Javascript虽然将数字存储为64位浮点数,但按位进行运算时,会将数字转换为32位整数。以前long,由于溢出,使用Java按位给出不同的结果时,我遇到了另一段代码的问题。
parsecer

(int)return行中删除演员表不会更改Java结果,而是保持不变-896768
parsecer

4
啊,我发现了问题。当您使用时... + 0x80000000,Java会将值转换为int,因为它0x80000000被视为int文字。将该数字更改为0x80000000L
约旦

1
@乔丹·哇,你是向导!有效!请发布您的答案,我会接受的
parsecer

Answers:


9

在Java中,0x80000000在32位int的范围之外,因此它回绕到-2147483648。

在JavaScript中,0x80000000处于64位double范围内,因此它仍然为2147483648。

显然,添加-2147483648与添加会2147483648导致很大的差异。

您可以long在Java中使用0x80000000L,也可以根据需要将JS号强制为32bit int (0x80000000|0)


2

尝试这个。在进行转换时,您需要指定长值。

    public static long normalizeHash(long encondindRound2) {
        if (encondindRound2 < 0) {
            encondindRound2 =  (encondindRound2 & 0x7fffffffL) + 0x80000000L;
        }

        return  (encondindRound2 % 1_000_000);
    }

但是,您还应该注意另一个问题。Javascript被视为%模运算符,而Java将其视为简单的余数运算符。在此处查看此帖子以获取更多信息。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.