Stata
Products Purchase Support Company
Search
   >> Home >> Resources & support >> FAQs >> Results of the mod(x,y) function Bookmark and Share
This FAQ is based on a question and answers that appeared on Statalist.

Why does the mod(x,y) function sometimes give puzzling results? Why is mod(0.3,0.1) not equal to 0?

Title   Results of the mod(x,y) function
Author Nicholas J. Cox, Durham University, UK
Thomas J. Steichen, RJRT
Date April 2001; updated February 2003; minor revisions September 2005

The mod(x,y) function (see [D] functions) is equivalent to x − y * floor(x/y). Here floor() returns the largest integer not greater than its argument, so that floor(2) = 2, floor(2.3) = 2, floor(−2) = −2, and floor(−2.3) = −3. In other words, it is the remainder on dividing x by y. It is obvious that 0.3 is a multiple of 0.1 and that the result should be 0, but given

        . display mod(0.3,0.1)

Stata shows 0.1.

Is this is a bug? Not really, but the result is unlikely to be what you want. It arises because int(0.3/0.1) = 2 to machine precision, and not 3, as expected from ordinary arithmetic. Hence, 0.1 is shown as the remainder or modulus.

Let us explain in more detail. Numbers like 0.3 and 0.1 cannot be held as exact binary equivalents; see [U] 13.10 Precision and problems therein. To show this, we will use %21.18f as a display format, which lets us see the underlying values, pretty much to the precision Stata sees them. (Stata also provides a special %21x format that shows the exact value in a special hexadecimal format, which you may wish to explore. This format was first available late in the product cycle of Stata 6.0. See also [U] 12.2 Numbers and [U] 12.5.1 Numeric formats.)

        . di %21.18f .3
        0.299999999999999990
        
        . di %21.18f .1
        0.100000000000000010

We are using essentially every bit here to get the closest machine decimal approximation we can to the true decimals 0.3 and 0.1. Clearly, neither number is represented exactly in the machine.

If we compare

        . di %21.18f .3/.1
        2.999999999999999600

with

        . di %21.18f 3
        3.000000000000000000

it is also clear that, in machine decimal, 3 is not equal to 0.3/0.1. This occurs because 3 can be represented accurately while 0.3/0.1 is just a smidgen smaller due to the approximations required to represent 0.3 and 0.1. Clearly, the integer portion of 0.3/0.1 = 2.999999999999999600 is 2, with the consequence that mod(0.3,0.1) is shown as 0.1 (more precisely, it is 0.099999999999999978 in machine decimal, but Stata's default display format rounds it to 0.1).

Users may get better results using float( ) and round( ), but perhaps the best advice is cautionary: it is safest not to try precision work using small fractional arguments to mod( ). You may be better advised to work at an equivalent problem using integers.

FAQs
What's new?
Statistics
Data management
Graphics
Programming Stata
Mata
Resources
Internet capabilities
Stata for Windows
Stata for Unix
Stata for Mac
Technical support
Resources & support
FAQs
Technical support
NetCourses
Short courses
Users Group meetings
Statalist
Links
Software updates
Software archives
Customer service
Manuals & supplements
Stata Journal
STB
Stata News
Stata Automation
Plugins

Site overview
Products
Resources & support
Company
Site index

© Copyright 1996–2009 StataCorp LP   |   Terms of use   |   Privacy   |   Contact us   |   Site index