Hàm Javascript được viết lại trong Java cho các kết quả khác nhau


9

Có chức năng Javascript này mà tôi đang cố gắng viết lại bằng Java:

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

Thích ứng Java của tôi:

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

Khi tôi vượt qua -1954896768, phiên bản Javascript trả về 70528, trong khi Java trả về -896768. Tôi cung không chăc tại sao. Sự khác biệt dường như bắt đầu bên trong điều kiện if: trong hàm Javascript sau if encodingRound2 = 2340070528, while trong Java : encodingRound2 = -1954896768.

Tôi đã thực hiện những thay thế này để hiển thị trực tuyến:

Javascript : https://repl.it/repls/NumbGuiltyHack

Java : https://repl.it/repls/ClumsyQualifiedProbols

EDIT : Thay đổi chức năng Java thành cái này

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

dường như không ảnh hưởng đến kết quả - nó vẫn -896768


1
Tại sao bạn encondindRound2chuyển sang một intmã Java? Vì được định nghĩa là a long, bạn sẽ có khả năng mất độ chính xác nếu bạn chuyển nó sang loại hẹp hơn.
Jordan

1
@Jordan bởi vì - bên trong if - có một thao tác bitwise đang được thực hiện trên nó. Javascript, mặc dù lưu trữ số dưới dạng float 64 bit, khi thực hiện theo bit, chuyển đổi số thành số nguyên 32 bit. Tôi đã gặp vấn đề này với một đoạn mã khác trước đây, khi thực hiện bitwise với Java longđã cho các kết quả khác nhau, vì tràn.
phân tích cú pháp

Việc xóa (int)cast khỏi returndòng không làm thay đổi kết quả Java, nó vẫn còn-896768
phân tích cú pháp

4
Ah, tôi tìm thấy vấn đề. Khi bạn giải quyết ... + 0x80000000, Java chuyển đổi giá trị thành int, vì 0x80000000được coi là int intal. Thay đổi số đó thành 0x80000000L.
Jordan

1
@Jordan Wow, bạn là phù thủy! Nó đã làm việc! Vui lòng gửi câu trả lời của bạn và tôi sẽ chấp nhận nó
phân tích cú pháp

Câu trả lời:


9

Trong Java, 0x80000000 nằm ngoài phạm vi của int 32 bit, do đó, nó bao bọc đến -2147483648.

Trong JavaScript, 0x80000000 nằm trong phạm vi gấp đôi 64 bit, do đó, nó vẫn là 2147483648.

Rõ ràng, thêm -2147483648so với thêm 2147483648kết quả trong một sự khác biệt rất lớn.

Bạn có thể sử dụng long0x80000000L trong Java hoặc ép buộc số JS của bạn thành số nguyên 32 bit (0x80000000|0), tùy theo bạn muốn.


2

Thử cái này. Bạn cần chỉ định các giá trị dài khi thực hiện chuyển đổi.

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

        return  (encondindRound2 % 1_000_000);
    }

Nhưng có một vấn đề khác bạn nên chú ý. Javascript xử lý %như một toán tử modulo trong đó Java coi nó như là một toán tử còn lại đơn giản. Kiểm tra bài này ở đây để biết thêm thông tin.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.