8
\$\begingroup\$

Machine epsilon is an important floating point number to know when doing numerical calculations. One way to understand it is when this relation

1 + machine_epsilon > 1

does not hold. One (iterative) way to extract it is executing a small program like the one above:

10 EPS=1
20 EPS=EPS/2
30 EPS1 = 1+EPS
40 IF EPS1 > 1 GOTO 20
50 PRINT EPS

But there may be more ways. Write the shortest code to extract the machine epsilon of your computer. NOTE: epsilon should be a non-zero value :)

\$\endgroup\$
2
  • 2
    \$\begingroup\$ no standard library (msdn.microsoft.com/en-us/library/system.single.epsilon.aspx ) nor literally typing out the memory representation of the epsilon? It's better to remind about it \$\endgroup\$
    – Ming-Tang
    Jul 19 '11 at 21:18
  • \$\begingroup\$ shinkirou: Read the page you linked: »Note: The value of the Epsilon property is not equivalent to machine epsilon, which represents the upper bound of the relative error due to rounding in floating-point arithmetic.« \$\endgroup\$
    – Joey
    Jul 20 '11 at 8:08

25 Answers 25

6
\$\begingroup\$

PowerShell, 5

Since .NET has certain guarantees for double, this number will not change, regardless of the implementation of the CLR or the platform it runs on. Therefore, the following suffices:

1/8pb

If you desperately need an iteration that computes the value in the way you've given in the task description, then that'd be 25 characters:

for($e=1;1+$e-1){$e/=2}$e
\$\endgroup\$
3
  • \$\begingroup\$ what is 8pb? so you mean that there is no way to calculate value doing some kind of iteration? \$\endgroup\$
    – leonardo
    Jul 19 '11 at 17:59
  • \$\begingroup\$ 8PB is 9007199254740992 (i.e. the number of bytes in eight pebibytes). Of course there is, but since it's always the same value there isn't much point in using longer code to achieve the same result, I guess. \$\endgroup\$
    – Joey
    Jul 19 '11 at 18:14
  • \$\begingroup\$ well, i am not so desperate :) thanks for your answer! \$\endgroup\$
    – leonardo
    Jul 19 '11 at 18:53
5
\$\begingroup\$

><> - 18 16 characters

1>2,:1v
n^?)1+<;

Usage and output using the python interpreter:

$ fish scripts/epsilon.fish 
1.1102230246251565e-16

Edit Fixed code to return correct value (1.1e-16)

\$\endgroup\$
2
  • \$\begingroup\$ impressed! nice compact code. \$\endgroup\$
    – leonardo
    Jul 19 '11 at 17:31
  • \$\begingroup\$ I don't think this is different enough to warrant its own answer (it's the same thing just put a different way). 14 bytes with this: line 1: 12,:1+1=0$. line 2: ;n \$\endgroup\$
    – cole
    Nov 6 '15 at 5:16
4
\$\begingroup\$

JavaScript, 28 characters

for(y=1;y+1-1;y/=2);alert(y)

I could replace the y+1-1 with y+1>1, but I like for aesthetics of the former.

\$\endgroup\$
3
\$\begingroup\$

Brainfuck, 16

Brainfuck doesn't support floating-point arithmetic, so epsilon is 0.

-[>-<+++++]>---.

According to this, this is the smallest such program. Program assumes that cells are unsigned bytes mod 256.

\$\endgroup\$
4
  • \$\begingroup\$ The Wikipedia page gives the following example: »A trivial example is the machine epsilon for integer arithmetic on processors without floating point formats; it is 1, because 1+1=2 is the smallest integer greater than 1.« \$\endgroup\$
    – Joey
    Jul 19 '11 at 19:53
  • 1
    \$\begingroup\$ Yeah... I'd tend to agree, but the problem asks for 1+eps <= 1. \$\endgroup\$
    – boothby
    Jul 19 '11 at 19:55
  • \$\begingroup\$ Hm, indeed. The answer should therefore be half the 2.2e-16 on WP for doubles (so the Fish one is probably wrong here). Ah well, fixing my answer yet again :) \$\endgroup\$
    – Joey
    Jul 19 '11 at 20:07
  • \$\begingroup\$ @Joey, my answer could be wrong here, but both the python answer and the python example on wikipedia both state 2.2e-16. The ><> script actually gives 1.1e-16, but it doubles it before printing because I figured it has to be the same as it's interpreted by python. If 1.1e-16 is the correct one, however, I'm happy as it'll save me 2 characters :P \$\endgroup\$
    – user1158
    Jul 19 '11 at 21:28
3
\$\begingroup\$

Perl

$x=1;push@a,$x/=2while$x;die@a[$#a-1];
\$\endgroup\$
2
\$\begingroup\$

Python, 29

t=1.
while t+1>1:t/=2
print t

Python3, 28

"true" division sucks, IMO... but I'll use it to cut a character out

t=1
while t+1>1:t/=2
print t
\$\endgroup\$
3
  • \$\begingroup\$ Your Python3 solution needs parantheses after print. \$\endgroup\$
    – Skyler
    Nov 4 '15 at 14:12
  • \$\begingroup\$ For reference, 10 bytes longer but also possible is: import sys;print sys.float_info.epsilon (documentation) \$\endgroup\$
    – agtoever
    Nov 5 '15 at 21:26
  • \$\begingroup\$ How do you do print t in python 3? \$\endgroup\$ May 3 at 14:46
2
\$\begingroup\$

Haskell

Update

until((==1).(1+))(/2)1

Previous:

For doubles

last$takeWhile(/=0)$iterate(/2)1

For floats

last$takeWhile(/=0)$iterate(/2)(1::Float)
\$\endgroup\$
1
  • 1
    \$\begingroup\$ I think you're looking for until(<=1)(\x->2/x+1)1. Still, though, I can't get ghci to produce anything other than 1.0. \$\endgroup\$ Jul 26 '11 at 1:18
2
\$\begingroup\$

PHP, 13 chars

For 1 + epsilon > 1, to be true, 1 + epsilon must fit into the number of bits allotted to the mantissa (5 in 5 * 10^4) in floating point numbers. 52 bits are allotted to the mantissa in 64-bit floating point numbers. It follows that 1 + epsilon is 1.000...(52)...0001 (base 2), and that episilon is 0.000...(52)...0001. Calculating this number in decimal gives:

<?=pow(2,-52);

You'll notice that negatively exponentiating 2 is the same as repeatedly dividing by 2 -- which is what many of the solutions here do.

Bonus, more platform-independent solution (13 chars):

<?=sin(pi());
\$\endgroup\$
2
\$\begingroup\$

MATLAB, 3 bytes

I'm going to post this purely because it's one of the rare opportunities for MATLAB to be one of if not the shortest. I think it is in the rules for what the question asks.

eps

Granted, not the most ingenious or exciting code though!

\$\endgroup\$
1
  • \$\begingroup\$ Now, let's golf this down... :) \$\endgroup\$
    – Sanchises
    Nov 5 '15 at 21:00
2
+50
\$\begingroup\$

Vyxal, 9 8 bytes

1{:›1>|½

LOTM finally gave me a reason to actually try Vyxal, and so far I like it!

-1 byte thanks to Aaron Miller

Try it Online!

\$\endgroup\$
3
  • \$\begingroup\$ Nice answer! Just so you know, Vyxal autocompletes a lot of structures, like the while loop, so you can leave off the ending } for 8 bytes. \$\endgroup\$ May 3 at 14:26
  • \$\begingroup\$ @AaronMiller Good to know, thanks! \$\endgroup\$
    – Citty
    May 3 at 14:31
  • \$\begingroup\$ very nicely done. bounty coming your way soon! \$\endgroup\$
    – lyxal
    May 5 at 6:31
1
\$\begingroup\$

Mathematica 15 chars

$MachineEpsilon

-> 2.220446049250313*10^-16
\$\endgroup\$
4
  • \$\begingroup\$ Generally, a Print is used for full programs in Mathematica. \$\endgroup\$ Nov 4 '15 at 12:26
  • \$\begingroup\$ @LegionMammal978 The purpose of Print[ ] in Mathematica is no other than to provide a method for generating output from intermediate results in a CompoundExpression[ ]. It can be normally replaced for the better by Sow[ _, tag] - Reap[_, tag] pairs. And no, you'll not see Print[ ] calls in well designed and functional Mathematica program. \$\endgroup\$ Nov 4 '15 at 14:01
  • \$\begingroup\$ I try to treat Mathematica programs I write here as if they are in a script, where there is no implicit output. \$\endgroup\$ Nov 4 '15 at 22:05
  • \$\begingroup\$ @LegionMammal978 Well, yes. You can try to do that. But it isn't what most Mathematica users do. You can check common programming conventions and pitfalls for example here or here \$\endgroup\$ Nov 4 '15 at 22:20
1
\$\begingroup\$

Ada - 151

generic
type T is digits <>;function E return T;function E return T is
A,B,C:T:=1.0;begin
loop
A:=A/2.0;B:=C+A;exit when B<=C;end loop;return A;end E;

example usage:

procedure Main is
   function F is new E (Float);
   function D is new E (Long_Float);
begin
   Put_Line ("Epsilon:" & Float'Image (F));
   Put_Line ("Epsilon:" & Long_Float'Image (D));
end Main;

output:

Epsilon: 5.96046E-08
Epsilon: 1.11022302462516E-16
\$\endgroup\$
1
\$\begingroup\$

Pyth - 5 bytes

.IhG1

Try it online here.

Invert goes through all positive reals till it finds something that makes the lambda of G equal the second arg. So the code just inverts 1+G till it equals 1.

\$\endgroup\$
1
\$\begingroup\$

Excel, 35 bytes

=LET(x,2^-ROW(1:99),MAX((1+x=1)*x))

Excel (2010), 37 bytes

=MAX(2^-ROW(1:99)*(1+2^-ROW(1:99)=1))
\$\endgroup\$
1
\$\begingroup\$

Java, 13 bytes

It is easy by using the ulp method.

Math.ulp(1.0)

Result is 2.220446049250313E-16.

\$\endgroup\$
1
\$\begingroup\$

Grok, 21 bytes

1Y  j qzph
>1+1hY/2p{

Try it Online!

That's right, there's an online interpreter now! For those wondering, the framework is modified from the online Vyxal interpreter.

Explanation:

1Y  j       # Push 1 and copy it to the register
  +1h       # Add 1
>1          # Is it greater than 1?
        p{  # If yes, retrieve value from register
     Y/2    # Divide by 2 and copy it to the register, then repeat this line
      qzph  # If no, retrieve value from register,
         {  # then print as a number
\$\endgroup\$
1
\$\begingroup\$

Husk, 8 bytes

Ωoε→½□√2

Try it online!

Formula is the exact same as the reference implementation.

Fixed with Leo's help by using decimals.

\$\endgroup\$
2
  • \$\begingroup\$ TIO times out because Husk uses arbitrary precision rationals, if you want to operate on floating point numbers you need to introduce non-rationals, for example starting from sqrt(2)^2 (but there may be shorter ways). Also, there is a built-in for looping until a certain condition is true: Try it online! \$\endgroup\$
    – Leo
    May 9 at 1:44
  • \$\begingroup\$ @Leo I thought Ω would be longer here. should've tried it out. \$\endgroup\$
    – Razetime
    May 9 at 2:00
0
\$\begingroup\$

Ruby, 18

Just for the sake of completeness:

p Float::EPSILON/2
\$\endgroup\$
0
\$\begingroup\$

Mathematica, 21 bytes

Print@$MachineEpsilon
\$\endgroup\$
0
\$\begingroup\$

JavaScript ES6 in a REPL,14

Number.EPSILON

JavaScript ES5 in a REPL,15

Math.pow(2,-52)
\$\endgroup\$
0
\$\begingroup\$

MMIX, 16 bytes (4 instrs)

(jelly xxd)

00000000: e0003ff0 21010001 06000100 f8010000  ṭ¡?ṅ!¢¡¢©¡¢¡ẏ¢¡¡

A bit of a hack: add 1 as int to 1.0, then subtract off as float. Disassembled:

eps SETH $0,#3FF0
    ADD  $1,$0,1
    FSUB $0,$1,$0
    POP  1,0
\$\endgroup\$
0
\$\begingroup\$

C++ (gcc), 63 bytes

#import<iostream>
int main(){long x=1;std::cout<<*(double*)&x;}

Try it online!

\$\endgroup\$
0
\$\begingroup\$

GNU AWK, 34 bytes

BEGIN{for(e=1;1+e>1;e/=2);print e}

Try it online! Features different epsilons for different precisions.

Thanks to GNU MPFR arithmetic, GAWK can rely on any arbitrary byte precision. GAWK's manual reference. The standard precision (double) returns 1.11022e-16.

Result:
0.000488281 half precision
5.96046e-08 single precision
1.11022e-16 double precision
9.62965e-35 quad precision
4.52784e-72 oct precision
\$\endgroup\$
0
\$\begingroup\$

05AB1E, 9 bytes

1[D>1›_#;

Try it online!

1[D>1›_#;  # full program
 [    _#   # while...
1 D        # literal...
  D        # or top of stack if not first iteration...
   >       # plus 1...
     ›     # is greater than...
    1      # literal...
        ;  # halve top of stack
           # implicit output
\$\endgroup\$
0
\$\begingroup\$

JavaScript (ES6), 24 bytes

(e=n=>n+1>1?e(n/2):n)(1)

Try it online!

Recursive solution, using the same algorithm as in the question.

Its body is an IIFE, so it's an expression that directly evaluates to the epsilon value.

(
  e = n =>       //Set e to the function, so we can call it later
    n + 1 > 1    //If n+1 is still greater than 1...
      ? e(n / 2) //...perform next iteration by calling itself with n halved
      : n        //...else, we found epsilon, return it
)(1)             //Call the function with the initial value 1

Fun fact: this will return the half of Number.EPSILON, as its value represents the smallest number that can be represented, i.e. Number.EPSILON + 1 > 1, while Number.EPSILON/2 + 1 === 1.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.