Java로 다시 작성된 Javascript 함수는 다른 결과를 제공합니다


9

Java로 다시 작성하려고하는이 Javascript 함수가 있습니다.

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

내 자바 적응 :

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

내가 통과 -1954896768하면 Javascript 버전이 반환 70528되고 Java는 반환 -896768됩니다. 왜 그런지 잘 모르겠습니다. 자바 스크립트 함수에서 후 같은 경우의 차이는 경우 조건 내에서 시작하는 것 같다 encodingRound2 = 2340070528동안 자바 : encodingRound2 = -1954896768.

나는이 repls를 온라인으로 보여주기 위해 만들었습니다.

자바 스크립트 : https://repl.it/repls/NumbGuiltyHack

자바 : https://repl.it/repls/ClumsyQualifiedProblem

편집 : Java 기능을 이것으로 변경

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

결과에 영향을 미치지 않는 것 같습니다-여전히 -896768


1
Java 코드로 캐스팅 encondindRound2하는 이유는 무엇 int입니까? 로 정의 long되었으므로 더 좁은 유형으로 캐스팅하면 정밀도가 떨어질 수 있습니다.
요르단

1
@Jordan은 if 내부에 비트 연산이 수행되기 때문에. Javascript는 64 비트 부동 소수점으로 숫자를 저장하지만 비트 단위로 수행하면 숫자를 32 비트 정수로 변환합니다. long오버플로로 인해 Java의 비트 단위로 비트 단위를 수행 할 때 다른 결과를 제공 할 때 전에 다른 코드 조각 에서이 문제가 발생했습니다 .
파 섹터

제거 단계 (int)로부터 캐스트 return자바 결과를 변경하지 않는 선을, 그것을 유지-896768
parsecer

4
아, 나는 문제를 발견했다. on을 선택 ... + 0x80000000하면 Java는 0x80000000int 리터럴로 간주 되므로 값을 int로 변환합니다 . 해당 번호를로 변경하십시오 0x80000000L.
요르단

1
@ 조던 와우, 당신은 마법사입니다! 효과가 있었다! 답변을 게시하고 나는 그것을 받아 드리겠습니다
parsecer

답변:


9

Java에서 0x80000000은 32 비트 int 범위를 벗어나므로 -2147483648으로 줄 바꿈됩니다.

JavaScript에서 0x80000000은 64 비트 double 범위 내에 있으므로 2147483648으로 유지됩니다.

분명히 더하기 -2147483648대 더하기 2147483648는 매우 큰 불일치를 초래합니다.

longJava에서 0x80000000L을 사용 하거나을 사용 하여 JS 번호를 32 비트 int로 강제 변환 할 수 (0x80000000|0)있습니다.


2

이 시도. 변환을 수행 할 때 긴 값을 지정해야합니다.

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

        return  (encondindRound2 % 1_000_000);
    }

그러나 알아야 할 또 다른 문제가 있습니다. Javascript는 %Java를 간단한 나머지 연산자로 취급하는 모듈로 연산자로 취급합니다. 이 게시물을 확인 여기에 대한 자세한 내용은.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.