DfType join(@NotNull DfType other, boolean exact) {
    if (other.isSuperType(this)) return other;
    if (this.isSuperType(other)) return this;
    if (other instanceof DfFloatConstantType) {
      float value = ((DfFloatConstantType)other).getValue();
      if (Float.isNaN(value)) {
        return create(myFrom, myTo, myInvert, true);
      }
      return joinRange(value, value, exact);
    }
    if (!(other instanceof DfFloatRangeType range)) {
      return exact ? null : TOP;
    }
    DfFloatRangeType res = range.myNaN && !myNaN ? new DfFloatRangeType(myFrom, myTo, myInvert, true) : this;
    if (range.myInvert) {
      if (range.myFrom > Float.NEGATIVE_INFINITY) {
        res = res.joinRange(Float.NEGATIVE_INFINITY, nextDown(range.myFrom), exact);
        if (res == null) return null;
      }
      if (range.myTo < Float.POSITIVE_INFINITY) {
        res = res.joinRange(nextUp(range.myTo), Float.POSITIVE_INFINITY, exact);
        if (res == null) return null;
      }
    } else {
      res = res.joinRange(range.myFrom, range.myTo, exact);
    }
    return res;
  }
DfType join(@NotNull DfType other, boolean exact)