diff --git a/src/V3Number.h b/src/V3Number.h index b565f2662..5c1645842 100644 --- a/src/V3Number.h +++ b/src/V3Number.h @@ -22,10 +22,19 @@ #include "V3Error.h" +#include +#include #include //============================================================================ +// Return if two numbers within Epsilon of each other +inline bool v3EpsilonEqual(double a, double b) { + return fabs(a - b) <= (std::numeric_limits::epsilon() * std::max(1.0, std::max(a, b))); +} + +//============================================================================ + class AstNode; class V3Number { diff --git a/src/V3Width.cpp b/src/V3Width.cpp index df700b182..3b54e14cf 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -4342,9 +4342,12 @@ private: AstNRelinker linker; nodep->unlinkFrBack(&linker); if (AstConst* constp = VN_CAST(nodep, Const)) { - // Ignore obvious conversions of whole real numbers, e.g. 1.0 -> 1 + // We convert to/from vlsint32 rather than use floor() as want to make sure is + // representable in integer's number of bits if (constp->isDouble() - && constp->num().toDouble() == floor(constp->num().toDouble())) { + && v3EpsilonEqual(constp->num().toDouble(), + static_cast( + static_cast(constp->num().toDouble())))) { warnOn = false; } }