3

I plotted the following in MATLAB and Desmos:

y = cos(x + 6998666554443343) (1)

The plot is shown here: Plot of (1)

This staircase behaviour seems to appear with any large number. The following plot with an extra digit in its phase is another example:

y = cos(x + 69986665544433456) (2) Plot of (2)

I think that I am crossing the limits of resolution somehow. Can someone explain the reason behind this 'staircase' behaviour?

  • 1
    Computers have limited precision (can only represent a finite amount of numerical values in memory), and this is most likely what's causing what you observed. In particular, floating point values (which is what is used under the hood) cannot represent all real numbers in their specified range; instead, there must be gaps between representable values, and things are arranged so that the gaps are (roughly speaking) tiny around zero, and large for very large values. In reality, it's a little bit more complicated than that; see https://courses.engr.illinois.edu/cs357/sp2023/notes/ref-4-fp.html – Filip Milovanović Jun 02 '23 at 12:55

2 Answers2

6

Matlab natively uses double precision floating point. As floating point values grow in magnitude the spacing between consecutive representable values gets larger. This spacing is referred to as machine epsilon and can be evaluated via eps in Matlab. For example, eps(6998666554443343) returns 1, which explains your first stair-stepped plot. eps(69986665544433456) returns 8, which is why your second plot is even coarser. Double precision only supports consecutive integer values up to 2^53 (see flintmax), which is ~9.0072e+15.

horchler
  • 3,274
  • 2
  • 27
  • 41
  • 4
    For anyone wondering why machine epsilon is so different between those two similar-looking numbers - the second one has one more digit. The first one is between $2^{52}$ and $2^{53}$; the second is between $2^{55}$ and $2^{56}$. – Michael Lugo Jun 02 '23 at 15:22
2

The large number you add is approximately $\approx10^{15}$. In binary this is close to $2^{15\log_2(10)}\approx2^{50}$. If the program is storing these as floats with $32$ bit precision, there will be a rounding error because it would require $50>32$ bits to store the number exactly. So, the number $x+6998666554443343$ is only kept to the first 32 bits, after which there is an error from rounding. The rounding function is discontinuous and looks like a staircase, jumping up in value suddenly.

If the underlying code switched to $64$-bit floats, the problem would go away.

Joshua Tilley
  • 10,619