# Argh, division doesn't work sometimes! Check this out...

• 03-26-2003
LuckY
Argh, division doesn't work sometimes! Check this out...
I feel like I am in the twilight zone. I have very simple arithmetic here, yet the compiler generates different results for some odd reason!
Basically I am dividing 731961 by 365.25 and the result should be exactly 2004 (no decimal). Here's some code:
Code:

```  unsigned x = 731961;   int y = 365;   std::cout << "\n" << x << " / " << (y + .25) << " = " <<     int(x / (y + .25));  //////////////////////////////////////// // what the eff???   std::cout << "\n-->" << x << " / " << (y + .25) << " = " <<     int(x / (365 + .25));    std::cout << "\n-->" << x << " / " << (y + .25) << " = " <<     int(x / (DPY + .25)); ////////////////////////////////////////   std::cout << "\n" << x << " / " << (y + .25) << " = " <<     int(731961 / (y + .25));    std::cout << "\n" << x << " / " << (y + .25) << " = " <<     int(731961 / (365 + .25));    std::cout << "\n" << x << " / " << (y + .25) << " = " <<     int(731961 / (DPY + .25));```
This outputs this:
Quote:

731961 / 365.25 = 2004
-->731961 / 365.25 = 2003
-->731961 / 365.25 = 2003
731961 / 365.25 = 2004
731961 / 365.25 = 2004
731961 / 365.25 = 2004
Do you have any effin clue why this is happening???? Argh!
• 03-26-2003
LuckY
Equivalently baffling:

I ran this and it worked fine (result was 2004):
Code:

```unsigned x = 731961; int y = 365; std::cout << "\n" << x << " / " << (y + .25) << " = " << int(x / (y + .25)) << std::endl;```
Then I ran this and it resulted in 2003:
Code:

```unsigned x = 731961; static const int y = 365; std::cout << "\n" << x << " / " << (y + .25) << " = " << int(x / (y + .25)) << std::endl;```

I also wanted to point out another twilight zone deal.
I have a member variable called _daycount. In a member function, I'm doing this:
// _daycount contains 731961
_daycount / 365.25
and it is returning 2003, again, instead of 2004 (this is origin of my problems).. Just pointing out that in the previous examples, the denominator was the problem, but in this case it's the numerator..

I am just about to cry... If you can help at all, please do :(
• 03-26-2003
Codeplug
That's pretty cool. What compiler/version are you two using? I always get 2004 in VC++ 6.0.

gg
• 03-26-2003
LuckY
Borland C++ 5.5.1

Pretty cool? hehe.. Yeah, if it's not your problem ;P

I suppose I could simply switch over to MSVC, but it's a library I'm writing and I'd really like it to work independent of the compiler. It does appear to be a compiler issue, but it is quite strange since I've never heard of or experienced such issues in the past.
Quite disturbing... ugh.
• 03-26-2003
LuckY
While I appreciate the sentiment, I am well acquainted with the manner in which floating point numbers are handled. To quote myself, since you quoted only a portion of my statement,
>I am dividing 731961 by 365.25 and the result should be exactly 2004 (no decimal)
Note the "no decimal" part. I wasn't referring to the way in which the computer was handling any truncation. Rather, I was stating that the mathematical statement 731961 / 365.25 is equivalent to 2004 (according to a calculator, iow).
Quote:

The reason for the different answers between
std::cout << "\n" << x << " / " << (y + .25) << " = " <<
int(x / (y + .25));

and

std::cout << "\n-->" << x << " / " << (y + .25) << " = " <<
int(x / (365 + .25));

is basically the way in which the various parts are promoted.
While at first there seems to be some validity to this idea, in all reality it doesn't make a difference in the end result. I have even declared y as a double, but it yielded the same results. Aside from that, as CodePlug mentioned, in MSVC the results were as they should be. Furthermore, were that the case, the following two lines would also evaluate to different values:
Code:

```  std::cout << "\n" << x << " / " << (y + .25) << " = " <<     int(731961 / (y + .25));    std::cout << "\n" << x << " / " << (y + .25) << " = " <<     int(731961 / (365 + .25));```
• 03-26-2003
Codeplug
I found some interresting stuff on http://www.eskimo.com/~scs/C-faq/top.html
Quote:

14.1: When I set a float variable to, say, 3.1, why is printf printing
it as 3.0999999?

A: Most computers use base 2 for floating-point numbers as well as
for integers. In base 2, one divided by ten is an infinitely-
repeating fraction (0.0001100110011...), so fractions such as
3.1 (which look like they can be exactly represented in decimal)
cannot be represented exactly in binary. Depending on how
carefully your compiler's binary/decimal conversion routines
(such as those used by printf) have been written, you may see
discrepancies when numbers (especially low-precision floats) not
exactly representable in base 2 are assigned or read in and then
printed (i.e. converted from base 10 to base 2 and back again).
...
14.4: My floating-point calculations are acting strangely and giving
me different answers on different machines.

A: First, see question 14.2 above.

If the problem isn't that simple, recall that digital computers
usually use floating-point formats which provide a close but by
no means exact simulation of real number arithmetic. Underflow,
cumulative precision loss, and other anomalies are often
troublesome.

Don't assume that floating-point results will be exact, and
especially don't assume that floating-point values can be
compared for equality. (Don't throw haphazard "fuzz factors"
in, either; see question 14.5.)

These problems are no worse for C than they are for any other
computer language. Certain aspects of floating-point are
question 11.34), otherwise a compiler for a machine without the
"right" model would have to do prohibitively expensive
emulations.

and workarounds appropriate for, floating-point work. A good
references below.

References: Kernighan and Plauger, _The Elements of Programming
Style_ Sec. 6 pp. 115-8; Knuth, Volume 2 chapter 4; David
Goldberg, "What Every Computer Scientist Should Know about
Floating-Point Arithmetic".
...
14.13: I'm having trouble with a Turbo C program which crashes and says
something like "floating point formats not linked."

A: Some compilers for small machines, including Borland's
(and Ritchie's original PDP-11 compiler), leave out certain
floating point support if it looks like it will not be needed.
In particular, the non-floating-point versions of printf()
and scanf() save space by not including code to handle %e, %f,
and %g. It happens that Borland's heuristics for determining
whether the program uses floating point are insufficient,
and the programmer must sometimes insert a dummy call to a
floating-point library function (such as sqrt(); any will
Notice the reference which Salem already posted :)

I would be interrested in knowing if the workaround in 14.13 solves the problem. If that doesn't work, see if explicitly casting the denominator to double works, ie. double(y + .25).

gg

[EDIT]
And casting both numerator and denominator....
• 03-26-2003
Stoned_Coder
The simple answer is to use integer calculations. Floting point to integer and back again after calcs done is hardly braintaxing stuff!
• 03-26-2003
LuckY
Quote:

see if explicitly casting the denominator to double works, ie. double(y + .25).
[EDIT]
And casting both numerator and denominator....
I already tried that... And that, but neither works ;)

Quote:

The simple answer is to use integer calculations. Floting point to integer and back again after calcs done is hardly braintaxing stuff!
For being a stoner, you are right on the ball... I don't know why I'm being such a lamebrain! I already had to do such a thing to perform a modulus operation, yet I totally lacked the brain power to dig that fact up for this mofo. Hehe. Thanks for pointing out the obvious (you would think), Stonethrower. I guess the surprising way in which the compiler was acting just threw me right off the ball...

Thanks again to all and to all a good night.
• 03-26-2003
Codeplug
Did you try the work around listed in "14.13" of the quote I posted?

gg
• 03-26-2003
Magos
Quote:

Originally posted by Salem
> Basically I am dividing 731961 by 365.25 and the result should be exactly 2004
There are no exacts when it comes to floating point. Floating point numbers are approximations, so mathematical answers (the correct ones) are sometimes different from the computational answers (the ones you have to live with).

But both 731961 and 365.25 can be expressed correctly in floating point numbers (assuming they follow the IEEE standard).
• 03-26-2003
LuckY
SparkPlug,
I did attempt to fix it using the suggestion in that article, alas, to no avail...