Page 1 of 1

[Oxyd] [0.17.14] Desync on math.ceil(-0.5)

Posted: Sun Mar 17, 2019 11:07 pm
by rlidwka
Run "/c game.print(tostring(math.ceil(-0.5)))".

Result on linux: 0

Result on windows: -0

I would expect to get the same value in order not to desync multiplayer maps if this code is used in custom scenario.

This may be somewhat relevant: viewtopic.php?f=182&t=62674

Re: [0.17.14] Desync on math.ceil(-0.5)

Posted: Sun Mar 17, 2019 11:30 pm
by TruePikachu
It's not related to the linked thread.

I am not actually sure what IEEE754 specifies as being the correct result, but according to the datasheet for my µM-FPU floating-point coprocessor (which has thus far followed IEEE754 specification), the correct result is, in fact, negative zero. However, according to `ceil(3)` (i.e. the Linux man page), `ceil(-0.5) = +0.0`.

Re: [0.17.14] Desync on math.ceil(-0.5)

Posted: Sun Mar 17, 2019 11:34 pm
by tehfreek
I just ran a quick test on my Linux system, and got some... strange results.

Code: Select all

#include <stdio.h>
#include <math.h>

int main(char* argv, int argc)
{
  printf("%f\n", -0);
  printf("%f\n", ceil(-0.5));
  printf("%f\n", -0);
}

Code: Select all

$ gcc -lm t.c
$ ./a.out 
0.000000
-0.000000
-0.000000

Re: [0.17.14] Desync on math.ceil(-0.5)

Posted: Sun Mar 17, 2019 11:40 pm
by TruePikachu
±0 is supposed to persist unchanged.

I ran a test of my own on my server box:

Code: Select all

#include <cmath>
#include <iostream>
using namespace std;

// NOTE: We're assuming IEEE754 float and double
volatile double input = -0.5; // `volatile` to prevent compile-time eval

int main() {
        double output = std::ceil(input);
        double* p_output = &output;
        uint64_t* ip_output = reinterpret_cast<uint64_t*>(p_output);
        uint64_t i_output = *ip_output;
        if(i_output >> 63)
                cout << "Negative zero" << endl;
        else
                cout << "Positive zero" << endl;
        return 0;
}

Code: Select all

chris:$ ./a.out
Negative zero

Re: [Oxyd] [0.17.14] Desync on math.ceil(-0.5)

Posted: Thu Jun 06, 2019 3:00 pm
by Oxyd
Indeed, ceil(-0.5) does return -0.0 on Linux. The problem was in how Lua would then convert the value to string for output.

Fixed in 0.17.46.

Re: [Oxyd] [0.17.14] Desync on math.ceil(-0.5)

Posted: Sat Jun 08, 2019 3:16 pm
by schmorp
tehfreak: your test program passes an int to %f, which results in undefined behaviour