Reputation: 117
(This is for an exercise) I'm trying to create a program that takes a double like 1.2041 and makes each decimal into an element in an array.
Through a loop I want the array to end up like this: ar[0] = 0.2; ar[1] = 0.00; ar[2] = 0.004; ar[3] = 0.0001;
After that I'm going to add the decimals together and end up with 0,2041 but I can't seem to find any way to reach out to each decimal alone.
I tried with multiplying and subtracting but I can't seem to get it to work.
Anyone know a simple way of making each decimal in a double into their own separate elements in an array?
Upvotes: 0
Views: 3123
Reputation: 153840
Unless you are keen to implement Dragon4 (see "How to Print Floating-Point Numbers Accurately" by Guy L.Steele Jr. and Jon L.White) you'd be best off to format the double
value into a string, e.g., using std::to_string()
, and compute the respective digit value [approximations] from that.
When representing a decimal value with fractional digits in a double
which is usually represented using a binary floating point representation the value generally get rounded. For example, it is impossible to exactly represent 0.1
using a double
. Instead, the closest representable value will be stored. When using an appropriate algorithm to recover a decimal representation, e.g., Dragon4 or Grisu (where the latter is typically faster but sometimes falls back to Dragon4 as far as I understand it) the original rounding is taken into account. These algorithms are somewhat non-trivial. You can find the source of a variation of Dragon4 in dtoa.c
by David Gay. You may want to have a look at more details in the article Here be dragons: advances in problems you didn’t even know you had.
When you use a naive approach trying to deduce each digit you'll get a value but at best you are getting the value actually represented by the double
. For example, your value 1.2041
is represented as 1.204099999999999948130380289512686431407928466796875
. The easiest way to see how a value is represented is to use the IEEE-754 Analysis: get two analyzers, enter the value into the first one, take the hexadecimal representation (in your case 3FF343FE5C91D14E
), and dump it into the second one. It will show the exact decimal value used by the double
.
Upvotes: 3
Reputation: 333
If you multiply by 10^n, and turn the result into an int, you'll get the whole number up to the wanted decimal. If you then get the remainder of that number divided with 10, you'll get only the number.
Then, you divide with 10^n and get the decimal:
(double)((int)(number/pow(10,n))%10)/pow(10,n)
That should do the trick.
NOTE: This code requires "math.h", number is the whole number, and n the decimal. n=1 is the first decimal.
Note 2: As Dietmar Kühl noted, this code has problems with the last decimal, as can be seen here: http://ideone.com/xOracn I'm looking for a workaround or a fix.
Upvotes: 1