Is it possible to create a decimal value that is perfectly precise?
On my computer, an integer value in C++ is 32 bits, and a long/double/long long are 64 bits. It is my belief, and correct me if this is wrong, that a floating point value has in the first part, a 1.xxxxx... multiplied by a mantissa. So in there you have a decimal, and the part after the 1 is a decimal value.
Therefore, would it be possible or has it been done, to simply “plop” 2 integers together and make a decimal value that is completely precise?
You would have then a maximum value of 4294967295.4294967295 or 2147483647.4294967295 for a signed value (the decimal would not need to be signed).
Has this been done before? If so why is it not popular in comparison to doubles and floats?
Yes and no
The short answer is that a variation on your proposal is used all the time for manipulating perfectly precise decimal strings. It’s not a native format for any popular computer so it is handled in software, but that hardly matters given the CPU speed these days. The key is to store the fraction as a base 10 decimal string.
Now, your proposal appears to be suggesting fixed point numbers with the binary decimal point in between bits 32 and 33. This has also been done, but it doesn’t solve the problem of decimal string fractions being unrepresentable.
You see, the problem is that a decimal string fraction is a rational number of the form x / (2n * 5m) and most of such values are not representable in a binary fraction which represents only x / 2n.
So, for example, between .01 and .99, only .25, .50, and .75 have exact binary representations. This is true of both IEEE floating point and of your fixed point proposal.
Now, if instead of a binary fixed point, you simply scale numbers by some power of 10, then all of your numbers will be exact. So, if your scale was 106, then $123.45 would be stored as 123450000.
That is, you have two choices. Because all whole numbers have an exact representation in either binary or decimal, you can either not store fractions, and simply scale as noted above, or you can store fractions, but do it internally with decimal digits. Say, allocate 4 bits per digit. This format is called BCD.
All of these techniques have been implemented countless times, so you don’t really have to do it yourself. Look at, for example, BigDecimal in Ruby.
If we were to redo civilization all over again, it might be convenient to pick a number base that is a power of two. All of these problems stem directly from the way we write fractional values IRL. We use decimal strings, which are mostly impossible to precisely represent as binary fractions.