Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Nan

182 views
Skip to first unread message

mse...@gmail.com

unread,
Jun 16, 2016, 9:01:42 AM6/16/16
to

I have an application which uses binary scan a lot to extract binary data.

under 8.4 a NaN passed to 'format %.6e' returned '1.#SNAN0e+000' or '1.#QNAN0e+000' with no error

Now I have 8.6 and I get the error 'floating point value is Not a Number'

the Inf and -Inf still return '1.#INF00e+000' and '-1.#INF00e+000' without an error.

Is there a specific reason that this was changes or a side effect of changes.

The problem is also that the NaN value is no longer just NaN but NaN(nnnnn) where nnnn is the specific NaN value

Martyn

kevin....@gmail.com

unread,
Jun 20, 2016, 10:34:29 AM6/20/16
to
The 1.#INF and 1.#SNAN are bugs - Microsoft's system library has a totally nonstandard way of handling infinity, not-a-number, and (if I recall correctly) denormals. They should format as just Inf and NaN, as you see if you print them without using [format].
The fix for that would be to have the %e, %f and %g format groups go through Tcl's own formatting rather than the system's 'sprintf', and we have about 80% of the plumbing to do that. I need to get back on that.

I'd also think that it would be appropriate to have [format] be permissive about NaN's. Most operations that take double's want to fail early, so many go through common code that complains when a NaN is passed in, but that seems too restrictive for [format].

The NaN(0xBADDECAFC0FFEE) is intentional. We have a subtle requirement that double's, when converted to string through the default pathway, need to reconvert to numbers (or Not-A-Number's) that are bit-for-bit identical to the original. (This is not possible for SNaN on all hardware, but we try, and we try to preserve all but the 'signalling' bit if we have to deal with it by downgrading to QNaN.)

Unfortunately, I don't have a lot of bandwidth to work on the Core just at the moment, so if you depend on me, a fix may well be delayed. (I do fully intend to get back, but even then, a lot of the effort is going to have to go into backfilling for Miguel, alas.)

mse...@gmail.com

unread,
Jun 21, 2016, 4:20:55 AM6/21/16
to
Thanks for the reply, the problem is for now in my unit tests, it would be nice that my output files had NaN or +/-Inf without adding specific checks to my code.

I try to process data as quickly as possible so every millisecond counts.

I will wait for now.
This should not arrive in normal use. unless there is a bitflip error ;-)

Martyn

Harald Oehlmann

unread,
Jun 21, 2016, 7:43:45 AM6/21/16
to
Thank you Kevin for your effort and work.
Is there already an open ticket?
It the text by Maryn ok for a ticket?

Thanks,
Harald

--- news://freenews.netfront.net/ - complaints: ne...@netfront.net ---

phil...@gmail.com

unread,
Jul 16, 2018, 8:13:05 PM7/16/18
to

I have another NaN issue - I wonder if it is related to this previously reported behavior in format.

The issue is that Tcl_GetDoubleFromObj no longer works on a value of NaN. This is in contradiction to string is double which still works fine.

To illustrate, here is a simple command added to a Tcl interpreter:

int pass_double(
ClientData c_data,
Tcl_Interp *interp,
int argc,
Tcl_Obj * CONST argv[]
)
{
const char* usage = "usage: pass_double double_obj";
if ( argc != 2 ) {
cout << usage << endl;
return TCL_ERROR;
}
double double_value;

Tcl_Obj *result_obj = Tcl_NewDoubleObj(0);
if (Tcl_GetDoubleFromObj(interp, argv[1], &double_value) != TCL_OK) {
cout << "C++: GetDoubleFromObj Failed" << endl;
cout << "C++: double_value is: " << double_value << endl;
// bool is_double = argv[1]->typePtr == &tclDoubleType;
// cout << "C++: Is it a double?: "<< is_double << endl;
double_value = argv[1]->internalRep.doubleValue;
cout << "C++: result_obj's internalRep.doubleValue is: " << double_value << endl;
return TCL_ERROR;
}
cout << "C++: GetDoubleFromObj Successful" << endl;
Tcl_SetDoubleObj(result_obj, double_value);
Tcl_SetObjResult(interp, result_obj);
return TCL_OK;

}

int Foo_Appinit( Tcl_Interp* interp ) {
if ((Tcl_Init)(interp) == TCL_ERROR) {
return TCL_ERROR;
}
Tcl_CreateObjCommand(interp, "pass_double", pass_double, NULL, NULL);
return TCL_OK;
}

int main( int argc, char* argv[] ) {
Tcl_FindExecutable(argv[0]);
Tcl_Main( argc, argv, &Foo_Appinit );

}

Under Tcl 8.4, the following code works fine:

puts "TCL: Sending variable valued as NaN to pass_double"
set dnan NaN
puts "string is double: [ string is double $dnan ]"

puts "--------------------"
puts "calling pass_double [ catch { pass_double $dnan } d ]"
puts "TCL: pass_double passes back: $d"

pass_double is sent the value of NaN, and it is able to access the value through Tcl_GetDoubleFromOjb.

In Tcl 8.6, that is no longer true (we are on Tcl 8.6.8).

This one is currently holding up our porting to Tcl 8.6.
0 new messages