# Why IntegerPart[x/(x/2)]=1?

Consider this code

x = 0.109354682484;
IntegerPart[x/(x/2)]
(* 1 *)

Precision[x]
(* MachinePrecision *)


Why does it give 1 ?

Version number: 9.0 on Mac 10.9.2

screenshot

Update:

If we use an undefined variable, IntegerPart[x0/(x0/2)] gives 2. Since Mathematica never gives warnings about this x0, I'm assuming for any x0 it is true.

If we calculate the same integer part using fortran, we get 2 instead of 1.

program main
implicit none

real(8):: x=0.109354682484
real(8):: y=1.4

write(*,*) int(x/(x/2))
write(*,*) nint(x/(x/2))
write(*,*) int(y)

end program main


compiled with ifort -O0 main.f90

output of above fortran code is

       2
2
1


according to here, int is a fortran intrinsic function that calculate the integer part.

Is this a bug?

-
Look at the FullForm of the result of x/(x/2). – chuy Apr 1 '14 at 17:23
I'm aware of that, but why fortran gives 2, with the same precision? – xslittlegrass Apr 1 '14 at 17:46
Then I guess it comes down to what you want IntegerPart[1.9999999999999998] to return? – chuy Apr 1 '14 at 17:50
Does your Fortran compiler optimize the expression x/(x/2)? – Michael E2 Apr 1 '14 at 18:00
@MichaelE2 I only use -O0 option but I don't know whether there are other optimizations. Are you aware of other optimizations? – xslittlegrass Apr 1 '14 at 18:07

The explanation is interesting here. I tried the same in C++, and worked a bit extra to make sure the compiler won't optimize away the divisions (looking at the assembly output, it may optimize it away if you're not careful). Indeed, I get 2 with C++.

And here's why:

C++ does the equivalent of

IntegerPart@Divide[x, Divide[x, 2]]

(* ==> 2 *)


while in Mathematica you're computing the equivalent of

x*(1/((1/2)*x))


which gives a different result.

If I do the calculation as (x* (1/ (0.5*x))) in C++, then the result is less than 2 and the integer part is 1.

Thanks! I never knew that a/b is interpreted as a*(1/b). That makes me worried a little bit about all the codes I have written. Actually I caught on this because of a strange behavior of my package, and it took me a whole morning to track down to problem to IntegerPart I used in that package. – xslittlegrass Apr 1 '14 at 18:54
The observed behavior is wrong under IEEE-754 as well as generic binary floating-point implementations. The result of x/2 or 0.5 * 2 has the same mantissa as x, and the exponent is decreased by one. Dividing two numbers having the same mantissa then results in a mantissa of 1 (stored implicitly), and the exponent is the difference in operand exponents. The only way for a binary implementation to not get exactly 2 for the result of x/(x/2) or x/(0.5*x) is if the scaled value becomes denormal. – Ben Voigt Apr 1 '14 at 23:13
@BenVoigt But as I said it does not compute x/(0.5*x). It computes x * (1/(0.5*x)). I don't know what's correct by the standard, but the result is precisely the same as what I get from C++, which just uses a few simple floating point instructions (based on the asm output). Mathematica also uses hardware floating point arithmetic by default. – Szabolcs Apr 2 '14 at 4:55