Tcl Source Code

View Ticket
Login
Ticket UUID: bf029ced86b614a4c29dc15b0ddc2b222e489004
Title: binary.test 40.3 signed NaN fails on IRIX/MIPS machines
Type: Bug Version: 8.6.6
Submitter: dexter1 Created on: 2017-01-11 21:22:44
Subsystem: 48. Number Handling Assigned To: nobody
Priority: 5 Medium Severity: Minor
Status: Open Last Modified: 2017-01-11 21:22:44
Resolution: None Closed By: nobody
    Closed on:
Description:
I've compiled tcl 8.6.6 from source.
System is a Challenge S server with MIPS R4400 processor. IRIX version is 6.5.22m and the compiler used is MIPSPro 7.4.4 with all available vendor-patches installed. CFLAGS are "-O2 -mips3 -n32"

When performing 'make test' it fails as follows:

==== binary-40.3 ScanNumber: NaN FAILED
==== Contents of test case:

    unset -nocomplain arg1
    list [binary scan \xff\xff\xff\xff f1 arg1] $arg1

---- Result was:
1 NaN(7ffffffffffff)
---- Result should have been (glob matching):
1 -NaN*
==== binary-40.3 FAILED

The test expects a single precision NaN with the sign bit set, because the original bit pattern's most significant bit is 1. A short version of this test is the following two-liner in tcl:

list [binary scan \xff\xff\xff\xff f1 arg1]
puts $arg1

which on the Challenge S produces:

cyane:~/tcltest> ../src/tcl8.6.6/unix/tcltest ./nan.tcl
NaN(7ffffffffffff)


It depends on the particular MIPS processor how the sign of a NaN result is stored and presented. Upon printing the NaN with a printf in C we discovered that the single precision NaN gets converted to a double precision NaN, with loss of the sign. An example:

#include <stdio.h>

int main(void)
{
        unsigned int i;
        unsigned long long x;

        x = 0xffffffffffffffff;
        printf("double of %llx is %f \n",x,*(double*)&x);

        x = 0x7fffffffffffffff;
        printf("double of %llx is %f \n",x,*(double*)&x);

        i = 0xffffffff;
        printf("float of %x is %f \n",i,*(float*)&i);

        i = 0x7fffffff;
        printf("float of %x is %f \n",i,*(float*)&i);

        return 0;
}

gives:

double of ffffffffffffffff is -nan0xffffffff 
double of 7fffffffffffffff is nan0xffffffff 
float of ffffffff is nan0x7fffffff 
float of 7fffffff is nan0x7fffffff 

This results happens for R4400 processors and R10000 processors as fellow enthusiasts have verified this. The double precision retains its sign, but the single precision does not. We believe that those processors handle conversion in hardware, different than for instance the R8000 processor. We haven't tested that processor yet however, due to the fact that they are very uncommon.

Because IEEE-754-2008 standard places no value to the sign bit and the NaN signs are not consistent on several MIPS Processors, i wonder if that explicit test for NaN with sign should be either be retained and disabled for IRIX or maybe weakened to disregard sign in the general case.