Bug 1475 - Test suite fails on ix86 due to unexpected rounding
Summary: Test suite fails on ix86 due to unexpected rounding
Alias: None
Product: libsigrok
Classification: Unclassified
Component: Portability (show other bugs)
Version: unreleased development snapshot
Hardware: All All
: Normal normal
Target Milestone: ---
Assignee: Nobody
Depends on:
Reported: 2020-01-01 15:44 CET by Stefan Brüns
Modified: 2020-01-01 19:03 CET (History)
0 users


Note You need to log in before you can comment on or make changes to this bug.
Description Stefan Brüns 2020-01-01 15:44:27 CET
tests/strutil.c:99:F:sr_samplerate_string:test_mhz:0: Invalid result for '1.034567 MHz': 1.034566 MHz (1034566).

The failing code is:
test_samplerate(uint64_t samplerate);

The error is caused by rounding of the "1.034567" float value. Depending on architecture and compiler flags, rounding is either up or down. The implicit cast to uint64_t truncates the value to the next smaller integer.

The result of this minimal test depends on the compiler flags, when using "-fexcess-precision=standard" (set by -std=c99) it rounds down, with "-fexcess-precision=fast" (e.g. set by -std=gnu99), it rounds up.

$> gcc-9 -Os -m32 -o round -fexcess-precision=standard round.c ;  ./round
#include <stdint.h>
#include <stdio.h>
#include <inttypes.h>

#define MHZ(x) ((x) * UINT64_C(1000000))

void t1(uint64_t x)
    printf("r: %" PRIu64 "\n", x);

void t2(float x)
    printf("r: %f\n", x);

int main(int argc, char** argv)
    if (argc < 2) {
        t1(MHZ(1.034567));               // 1034567 or 1034566
        t1(MHZ(1.03456700000000000001)); // 1034567 or 1034566
        t1(MHZ(1.0345670000000000001));  // 1034567
    return 0;
Comment 1 Stefan Brüns 2020-01-01 19:03:18 CET
Possible mitigations:

- use "test_samplerate(round(SR_MHZ(x))"
- change test_samplerate(uint64_t) to test_samplerate(double) and do the round inside test_samplerate.