Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why different results of 0.5 mod 0.1 in different programming languages?

Tags:

.net

php

modulo

I have a question about modulo. The modulo operation finds the remainder of division of one number by another. I was expecting that the result of 0.5 % 0.1 = 0. But when I run this in PHP or .net I get 0.1.

The code in php I ran was:

var_dump(fmod(0.5, 0.1));

In .net I tried the following for the outcome:

Console.WriteLine(0.5%0.1);

I also tried an online calculator http://www.calculatorpro.com/modulo-calculator/.

All these 3 methods gave me 0.1 as answer.

But when I type this in google I get the result I expected http://www.google.nl/search?source=ig&hl=nl&q=0.5%20mod%200.1&meta=.

Is this an bug in .net/php or does google know the right answer? Can anyone explain why these differences occur?

like image 273
Wessel Kranenborg Avatar asked Apr 11 '11 07:04

Wessel Kranenborg


3 Answers

The number you get in PHP or C# or C++ or Python or whatever when you ask for 0.1 is a double-precision floating-point number, which means it's a finite "decimal" -- with 53 significant bits including the first 1-bit -- in base 2. In fact what you'll get is the nearest exactly-representable number to 0.1, which I think is exactly 0.1000000000000000055511151231257827021181583404541015625.

On the other hand, 0.5 is a finite "bicimal"; the value you get when you ask for that will be exactly 0.5.

Therefore, 0.5 is just a little bit less than 5 times "0.1", and therefore "0.5 mod 0.1" actually gives you something a little bit less than 0.1. In fact, I think it's exactly 0.09999999999999997779553950749686919152736663818359375.

Now, when you ask PHP or C# or whatever to display this number, it will display some limited number of digits. You don't really want it to display the whole ghastly thing. (Consider: suppose you just ask for 0.1 to be displayed; do you want an umpteen-digit monstrosity, or do you want "0.1"? Thought so.) And the number is in fact very close to 0.1; unless you ask for more than 15 digits of precision the correct thing to display is just "0.1".

Observe (this is Python, which I happened to have handy):

>>> for n in range(10,20): print (("%%.%dg"%n)%(0.5%0.1))

0.1
0.1
0.1
0.1
0.1
0.1
0.09999999999999998
0.099999999999999978
0.0999999999999999778
0.0999999999999999778

So: not a bug; not really a matter of floating-point being inappropriate for "precision calculations" (sometimes it's appropriate, sometimes not; the thing is to understand what it's doing and what you need); may or may not indicate that you'd have done better to use integers, depending on what your real need is.

For much more about this stuff than you probably want to know, take a look at "What every computer scientist should know about floating-point arithmetic".

As for why Google's calculator gives the expected answer of 0, I don't know. Perhaps they're using decimal arithmetic -- real base-10 numbers -- to minimize unexpected surprises. (This is typically much slower than using native floating-point, but Google has a lot of CPU available and I bet only a tiny fraction of the work their search-handling machines do has anything to do with the calculator.)

like image 143
Gareth McCaughan Avatar answered Sep 28 '22 08:09

Gareth McCaughan


No this is not a bug, since the modulo operation can be defined on floating point numbers, too. In your PHP code you are explicitely using fmod() instead of % and in .NET the % operator is defined on every numeric type (check reference)

like image 21
Michael Rose Avatar answered Sep 28 '22 08:09

Michael Rose


0 is the integer answer and 0.1 is the right float result

additionally look at wolframalpha: http://www.wolframalpha.com/input/?i=0.5+mod+0.1

like image 26
Fender Avatar answered Sep 28 '22 09:09

Fender