Skip to content
This repository has been archived by the owner on Jul 8, 2022. It is now read-only.

Added support for negative NaN in Tango properties. #371

Merged
merged 2 commits into from
Jun 15, 2017

Conversation

bourtemb
Copy link
Member

@bourtemb bourtemb commented Jun 1, 2017

A negative NaN will be extracted as NaN.

A negative NaN will be extracted as NaN.
@bourtemb
Copy link
Member Author

bourtemb commented Jun 1, 2017

In this version, properties having -NaN as value will be extracted as a NaN (not -NaN) when using the DbDatum extractors for double and float (scalars and vectors)...
Could this be a problem? Does anyone think it would be more useful/meaningful to extract them as -NaN?

@t-b
Copy link
Collaborator

t-b commented Jun 1, 2017

@bourtemb I think folding -NaN to NaN is a good thing. According to IEEE754 any operation on NaN is NaN again so -NaN == NaN.

I'm actually wondering how you get -NaN in tango in the first place.

@bourtemb
Copy link
Member Author

bourtemb commented Jun 2, 2017

It looks like we have an example of device server getting some computation results from Matlab.
In these results, there are some -NaN values.
The device server stores these values into a Tango property.
Tango is using an ostringstream to convert float or double data into a string (all the properties are stored as string in the Tango database).
Here is the code which is doing the conversion into string:

void DbDatum::operator << (vector<double>& datum)
{
	ostringstream ostream;
	value_string.resize(datum.size());

	for (unsigned int i=0; i<datum.size(); i++)
	{
		ostream << std::setprecision(TANGO_FLOAT_PRECISION) << datum[i];
		value_string[i] = ostream.str();
		ostream.str("");
	}

	value_type = DEVVAR_DOUBLEARRAY;
	value_size = datum.size();
}

When datum[i] == -NaN, then this is converted as "-nan" string by this code.
We could eventually add a line of code here to convert -nan into nan before to write the property too.

@t-b
Copy link
Collaborator

t-b commented Jun 2, 2017

So just that I understand the motivation. Before this PR you could not readback negative NaNs written into a Tango property?

@bourtemb
Copy link
Member Author

bourtemb commented Jun 2, 2017

Right you are.
And if you had a double array property for instance, with a -NaN in the middle of the values, then, Tango would convert the -NaN to 0 as well as all the values behind the -NaN value.
The same behaviour happened before #362 too with Nan and +/-inf

@t-b
Copy link
Collaborator

t-b commented Jun 2, 2017

Thanks for the clarification. I think that is a reasonable fix for already stored -NaN properties.

But I'm a bit puzzled why does ostringstream serialize a negative Nan as "-NaN" in the first place?

Using the following test program

#include <iostream>
#include <limits>
#include <sstream>

int main(int argc, char** argv)
{
  {
    std::stringstream str;
    str << std::numeric_limits<double>::quiet_NaN() << std::endl;
    std::cout << str.str();
  }

  if(argc < 2)
    return 1;

  double val = 0.0;
  sscanf(argv[1], "%lf", &val);

  std::cout << val << std::endl;

  {
    std::stringstream str;
    str << (val * std::numeric_limits<double>::quiet_NaN()) << std::endl;
    std::cout << str.str();
  }

  return 0;
}

I get

$ g++ test.c && ./a.exe -1
nan
-1
nan

with

$ g++ --version
g++.exe (i686-posix-dwarf-rev0, Built by MinGW-W64 project) 6.2.0
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

So a standard stringstream never serializes a -NaN to "-NaN".

@bourtemb
Copy link
Member Author

bourtemb commented Jun 2, 2017

I think you misunderstood me...
If you do:
{
std::stringstream str;
double myDouble = -std::numeric_limits::quiet_NaN();
str << myDouble << std::endl;
std::cout << str.str();
}

This will print:

-nan

As I said, we have a device server which gets data from a Matlab program and in these data, we get some -NaN...
These -NaN are already in a double variable.

@t-b
Copy link
Collaborator

t-b commented Jun 2, 2017

With what compiler are you getting that? If I try your code with my above compiler I'm getting nan.

#include <iostream>
#include <limits>
#include <sstream>

int main(int argc, char** argv)
{
  double ttest = -std::numeric_limits<double>::quiet_NaN();
  std::stringstream str;
  str << ttest << std::endl;
  std::cout << str.str();

  return 0;
}

Disregarding the reason why we have -NaN in a string I think your suggested changes are good.

@bourtemb
Copy link
Member Author

bourtemb commented Jun 4, 2017

I get -nan with g++ 4.7.2 (Debian 8) and g++ 4.7.2 (Debian 7).
Good to know this has been fixed in recent versions.
Thank you very much for your feedback.

@t-b
Copy link
Collaborator

t-b commented Jun 4, 2017

The above tests were with gcc 6.2 on windows.

I also get -NaN with gcc 6.3 on debian stretch. So this seems a platform dependent problem.

@bourtemb bourtemb merged commit d504cd6 into tango-9-lts Jun 15, 2017
@bourtemb bourtemb deleted the negative_nan_in_prop branch June 21, 2017 15:38
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants