This misunderstanding is common to many languages not only Perl, because people expect a decimal calculation behind decimal representation.

But 4/25 isn't a number which can be accurately represented in a binary system and rounding errors come into play.

##### update

To elaborate further

(4*1000)/25 is an integer but 1000*(4/25) is a float with a very tiny error in the last bits of the mantissa.

Perl will still print this float like an integer because the error is too small.

But after the subtraction the leading zeros in the mantissa will cause a left shift (with adjustment of the exponent).

This means the error shifts out of Perl's tolerance margin and is printed as (decimal) fraction.

Cheers Rolf
(addicted to the Perl Programming Language and ☆☆☆☆ :)
Je suis Charlie!

• Comment on Re: Integers sometimes turn into Reals after substraction

Replies are listed 'Best First'.
Re^2: Integers sometimes turn into Reals after substraction
by rduke15 (Beadle) on May 14, 2016 at 11:50 UTC
Well, I understand that. The problem is that it is inconsistent. The result depends not only on the type of calculation which led to \$x2:
```perl -e '\$x1=256080; \$x2 = 1000 * ( 4*60 + 18 + 4/25 ); \$diff=\$x2-\$x1; print "x1=\$x1, x2=\$x2, diff=\$diff\n";'
x1=256080, x2=258160, diff=2080.00000000003```
```perl -e '\$x1=256080; \$x2 = 1000 * ( 4*60 + 18 ) + 1000*(4/25); \$diff=\$x2-\$x1; print "x1=\$x1, x2=\$x2, diff=\$diff\n";'
x1=256080, x2=258160, diff=2080```

but also on the value of \$x1 which has never been calculated.

```perl -e '\$x1=25608; \$x2 = 1000 * ( 4*60 + 18 + 4/25 ); \$diff=\$x2-\$x1; print "x1=\$x1, x2=\$x2, diff=\$diff\n";'
x1=25608, x2=258160, diff=232552```
Have you seen the update in my reply?

##### update

Think float, this

```x1   = 256080
x2   = 258160
diff = 2080.00000000003

really just means (in slightly inaccurate decimal interpretation)

```x1   = 2.56080            e5
x2   = 2.5816000000000003 e5  (error ignored when printed)
diff = 2.08000000000003   e3  (error visible when printed)

As you can see the error (here decimal 3) is shifted to the left and out of error margin into printed "visibility".

##### update

after firing up my laptop, here a proof of concept

```  DB<115> \$x1 = 2.56080e5
=> 256080

DB<116> \$x2 = 2.5816000000000003e5
=> 258160                 # within error margin, ignored in normal di
+splay

DB<117> printf '%.11f', \$x2
258160.00000000003         # forced into visibility, hence \$x2 NOT an
+integer

DB<118> \$x2-\$x1
=> 2080.00000000003       # error can't be ignored any more