I think I found a bug in Matlab. My only explanation is, that matlab calculates internally with other values than the ones which are displayed:
K>> calc(1,11)
ans =
4.000000000000000
K>> floor(ans)
ans =
3
Displayed code is an output from the Matlab console. calc(x,y) is just an array of double values.
MATLAB uses the standard IEEE floating point form to store a double.
See that if we subtract off a tiny amount from 4, MATLAB still diplays 4 as the result.
>> format long g
>> 4 - eps(2)
ans =
4
In fact, MATLAB stores the number in a binary form. We can see the decimal version of that number as:
>> sprintf('%.55f',4-eps(2))
ans =
3.9999999999999995559107901499373838305473327636718750000
Clearly MATLAB should not display that entire mess of digits, but by rounding the result to 15 digits, we get 4 for the display.
Clearly, the value in calc(1,11) is such a number, represented internally as less than 4 by just a hair too little that it rounds to 4 on display, but it is NOT exactly 4.
NEVER trust the least significant displayed digit of a result in floating point arithmetic.
Edit:
You seem to think that 3.999999999999999 in MATLAB should be less than 4. Logically, this makes sense. But what happens when you supply that number? AH yes, the granularity of a floating point double is larger than that. MATLAB cannot represent it as a number less than 4. It rounds that number UP to EXACTLY 4 internally.
>> sprintf('%.55f',3.9999999999999999)
ans =
4.0000000000000000000000000000000000000000000000000000000
What you got was a value really close to but lower than 4, and even with format long Matlab has to round to the 15th digit to display the number.
Try this:
format long
asd = 3.9999999999999997 %first not-9 @16th digit
will print 4.000000000000000. Anyone who doesn't know the actual value of asd based on what gets visualized would guess it is at least 4, but running
asd >= 4
gives 0, and so floor(asd) returns 3.
So is a matter of how Matlab rounds the displayed output, the true value stored in the variable is less than 4.
UPDATE:
if you go further with the digits, like 18x9:
>> asd = 3.999999999999999999
asd =
4
>> asd == 4
ans =
1
asd becomes exactly 4! (notice it doesn't display 4.000000000000000 anymore) But that's another story, is no more about rounding the number to have a prettier output, but about how the floating point arithmetic works... Real numbers can be represented up to a certain relative precision: in this case the number you gave is so close to 4 that it becomes 4 itself. Take a look to the Python link posted in the comment by @gokcehan, or here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With