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

This subforum contains all the issues which we already resolved.
Post Reply
rlidwka
Burner Inserter
Burner Inserter
Posts: 8
Joined: Sun Mar 17, 2019 10:43 pm
Contact:

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

Post 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

User avatar
TruePikachu
Filter Inserter
Filter Inserter
Posts: 978
Joined: Sat Apr 09, 2016 8:39 pm
Contact:

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

Post 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`.

tehfreek
Filter Inserter
Filter Inserter
Posts: 391
Joined: Thu Mar 17, 2016 7:34 am
Contact:

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

Post 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

User avatar
TruePikachu
Filter Inserter
Filter Inserter
Posts: 978
Joined: Sat Apr 09, 2016 8:39 pm
Contact:

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

Post 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

Oxyd
Former Staff
Former Staff
Posts: 1428
Joined: Thu May 07, 2015 8:42 am
Contact:

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

Post 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.

schmorp
Manual Inserter
Manual Inserter
Posts: 3
Joined: Wed Apr 17, 2019 8:01 am
Contact:

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

Post by schmorp »

tehfreak: your test program passes an int to %f, which results in undefined behaviour

Post Reply

Return to “Resolved Problems and Bugs”