-1

I am working on converting some software to using the fmt library, which was previously using a combination of double-conversion, iostream, and boost::format. The majority of numeric values being output are double precision floating point, and we have a number of tests which check for corner cases involving infinities, nan, etc.

My problem is that, with fmt, many of the test outputs have changed to display negative-not-numbers: -nan, which is a completely nonsense concept to me.

I realize that IEEE-754 spec allows for a large number of different bit representations of nans, including the sign bit being either set or cleared. But all I want to know is if a value is a number or not. Once a value is nan, I don't care if someone has attempted to negate that value. The result of any arithmetic on nan should just be nan. The negative sign adds no meaningful value.

So how can I omit the negative sign on double -nan values when using libfmt?

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
peepsalot
  • 422
  • 4
  • 7
  • Are you getting these NaN values from something you can change? That is, can you convert the values into non-negative NaNs? – Nicol Bolas Jan 15 '23 at 02:53

1 Answers1

0

I ended up making a wrapper class for doubles and defining a custom formatter for it, which solves the issue I was having.

#include <cmath> // for std::isnan

struct Numeric {
  Numeric() = default;
  Numeric(double d) : value(d) { }
  double value = 0.0;
};

template <> struct fmt::formatter<Numeric> : fmt::formatter<double> {
  // parse function inherited from formatter<double>
  template <typename FormatContext>
  auto format(const Numeric& n, FormatContext& ctx) const -> decltype(ctx.out()) {
    return std::isnan(n.value) ?
      fmt::format_to(ctx.out(), "nan") :       // avoid output of "-nan"
      formatter<double>::format(n.value, ctx); // otherwise use inherited format function
  }
};
peepsalot
  • 422
  • 4
  • 7
  • So changing a bunch of code to use the wrapper is acceptable, but changing tests to check the right string is not? :/ – HolyBlackCat Jan 18 '23 at 07:07
  • 1
    @HolyBlackCat Yes. As regression tests, they are designed to catch unintended changes in behavior, where users are already accustomed to the existing behavior (there being no such thing as negative-not-a-number). So I am more willing to workaround with a wrapper than to change behavior due to quirks in one dependency. – peepsalot Jan 18 '23 at 07:19