1
using Num = std::variant<int64_t, double>;

std::vector<int64_t> intsOnly  = makeInts();
std::vector<Num> intsAndFloats = makeIntsAndFloats();

int64_t  iResult = 0;
for (auto i: intsOnlys) {
  iResult += i;
}

double dResult = 0.0;
for (auto d: intsAndFloats) {
  dResult += extractValue(d); // function always returns double type.
}

assert(iResult == int64_t(dResult));

If the variable intsAndFloats contains only ints, will the above assertion always hold, or is the double type not able to represent certain int64_t values, in some cases?

My usecase is that I'm creating a toy compiler, and I want the result type of an addition to be int or real, depending on the arguments to a function add. Like:

// If any of the arguments is a real, then the result is a real; else, it's an int.
(add $a $b $c ... $n)

Currently, I'm iterating over the argument list twice: once to see if there are doubles present, and another to perform the actual addition. I'd like to avoid that, if possible.

// Iterate over the list once, to set hasFloat. Then ...

if (hasFloat) {
  double result = 0.0;
  for (auto i: args) {
    result += isInt(i) ? getInt(i) : getFloat(i);
  }
  return returnFloat(result);
} else { // has no floats.
  int64_t result = 0;
  for (auto i: args) {
    result += getInt(i);
  }
  return returnInt(result);
}
Dess
  • 2,064
  • 19
  • 35
  • 3
    TL;DR of the dupe: No, you'll get 53 bits of precision. – NathanOliver Apr 21 '20 at 16:31
  • I'm sure this has been answered a bajillion times, but I can't find one now. The answer is no. The mantissa in a typical `double` has 53 bits; you can't jam 64 bits of value into it. – Pete Becker Apr 21 '20 at 16:31
  • A typical `double` is represented using 64 bits (i.e. the upper limit of the number of distinct values it can represent is the same as a 64-bit integer). However, floating point variables can represents a larger range of values. That means it is impossible for a `double` to represent all the values that an `int64_t` can. – Peter Apr 21 '20 at 16:33
  • [Here's](https://www.exploringbinary.com/the-spacing-of-binary-floating-point-numbers/) an interesting read on the topic. – 0x5453 Apr 21 '20 at 16:34
  • 1
    Even without knowing how floating point math works - Two numeric types of the same size can represent the same number of values. If one has a larger range than the other then it necessarily can not represent some values of the other. – Rotem Apr 21 '20 at 16:34
  • No. A `double` can represent `0.5`. If a `double` as 64-bits could represent that and all the 2^64 different values of `int64_t`, that would take more than the 64-bits of `double` to encode. Something has to give. A `double` can represent all the values of `int54_t`. – chux - Reinstate Monica Apr 21 '20 at 19:58
  • @Rotem: That is not strictly true. Two types with the same size may have different numbers of padding bits, so the values of one may be a strict subset of the values of the other. (This is not the case with `int64_t`, however.) – Eric Postpischil Apr 21 '20 at 20:23
  • @EricPostpischil Ok, can be rephrased as 'same number of data bits'. – Rotem Apr 21 '20 at 20:25

0 Answers0