0

I am trying to solve a kata from "codewars" in c++. I should calculate the digital root. One test case should calculate the digital root of 167346 to be 9. My code calculates 0 plus 6 to be 5, within the first run.

int digital_root(int n, int rtn = 0) {
   double fract(0), intval(0), dn(n);
   dn = dn / 10.0;
   fract = modf(dn, &intval);

   std::cout << "rtn before : " << rtn << std::endl;
   std::cout << "fract : " << fract << std::endl;
   std::cout << "fract times 10 : " << fract*10 << std::endl;

   rtn+=(fract*10.0);

   std::cout << "rtn plus fract times 10 : " << rtn << std::endl;

   if (rtn < 10 && intval == 0)
     return rtn;
   else if (rtn > 10 && intval == 0)
     return digital_root(rtn, 0);

   return digital_root(intval, rtn);
}

That generates the output:

rtn before : 0
fract : 0.6
fract times 10 : 6
rtn plus fract times 10 : 5
rtn before : 5
fract : 0.4
fract times 10 : 4
rtn plus fract times 10 : 9
rtn before : 9
fract : 0.3
fract times 10 : 3
rtn plus fract times 10 : 12
rtn before : 12
fract : 0.7
fract times 10 : 7
rtn plus fract times 10 : 18
rtn before : 18
fract : 0.6
fract times 10 : 6
rtn plus fract times 10 : 24
rtn before : 24
fract : 0.1
fract times 10 : 1
rtn plus fract times 10 : 25
rtn before : 0
fract : 0.5
fract times 10 : 5
rtn plus fract times 10 : 5
rtn before : 5
fract : 0.2
fract times 10 : 2
rtn plus fract times 10 : 7

How can 0 plus 6 can be 5?

phuclv
  • 37,963
  • 15
  • 156
  • 475
chris576
  • 63
  • 5
  • 5
    It is not wise to use floating-point numbers to solve tasks that consist of whole numbers only. – heap underrun Jun 02 '22 at 08:40
  • This exercice can easily be implemented with `int` values only. This would be little simpler, and also faster. If you persist to use `double` for internal computation, remember to always **round** values before converting them back to `int`. – prapin Jun 02 '22 at 08:52
  • 1
    It can be true for very small values of 6. – eerorika Jun 02 '22 at 08:54
  • Which compiler are you using? This is caused by floating point inaccuracies (`0.6` is actually `0.599999`) but on the compilers I've tested with you still get the expected result of `6`: https://godbolt.org/z/q77GTdzs8 – Alan Birtles Jun 02 '22 at 08:56
  • @AlanBirtles floating point arithmetic is standardized by the IEEE754. In theory it is reproducible and independent of the compiler (at least for standard conformant compilers). – Jakob Stark Jun 02 '22 at 09:26
  • @JakobStark not all compilers strictly implement IEE754 though, especially older ones or ones with fast math enabled – Alan Birtles Jun 02 '22 at 11:32

0 Answers0