BigQuery JavaScript UDFs return different output compared with standard JavaScript.

Output from Bigquery : 3540200

Output from standard Javascript environment : 354021

CREATE temp FUNCTION getmeshcode(meshnum INT64, x FLOAT64, y FLOAT64) RETURNS STRING LANGUAGE js AS R"""
const MINIMUM_LON = 122.00;
const MAXIMUM_LON = 154.00;
const MINIMUM_LAT = 20.00;
const MAXIMUM_LAT = 46.00;

const FIRST_MESH_SIZE = [1, 2 / 3];

const MESH_INFOS = [
    null,
    {parent: 1, ratio: 1},
    {parent: 1, ratio: 8},
    {parent: 2, ratio: 10},
    {parent: 3, ratio: 2},
    {parent: 4, ratio: 2},
    {parent: 5, ratio: 2},
    {parent: 3, ratio: 10},
    {parent: 7, ratio: 2},
    {parent: 7, ratio: 10},
    {parent: 9, ratio: 2},
];

function getMeshCode(meshnum, x, y) {
    const ratio = MESH_INFOS[meshnum].ratio;
    const parent = MESH_INFOS[meshnum].parent;
    if (meshnum === 1) {
        return "";
    } else if (meshnum === 4 || meshnum === 5 || meshnum === 6) {
        return getMeshCode(parent, Math.floor(x / ratio), Math.floor(y / ratio)) + String((y % ratio) * 2 + (x % ratio) + 1);

    } 
    else {
        return getMeshCode(parent, Math.floor(x / ratio), Math.floor(y / ratio)) + String(y % ratio) + String(x % ratio);
    }
}

return getMeshCode(meshnum, x, y);
""";
SELECT getmeshcode(5, 5642,7496)

Would you like to help me out?

Upon replication this is due to by default Javascript numbers are always 64 bit floating point[1]. In BQ UDF meshnum is declared in Float64 which produces different results when applying this parameter to the else if line part of the code.

Int64:

Float64:

[1]https://www.w3schools.com/js/js_numbers.asp#:~:text=JavaScript%20Numbers%20are%20Always%2064%2Dbit%20Floating%20Point

1 Like