1

I'm trying to find the max machine number x that satisfies the following equation: x+a=a, where a is a given integer. (I'm not allowed to use eps.)

Here's my code (which is not really working):

function [] = Largest_x()

a=2184;
x=0.0000000001
while (x+a)~=a
    x=2*x;
end
fprintf('The biggest value of x in order that x+a=a \n (where a is equal to %g) is : %g \n',a,x);
end

Any help would be much appreciated.

  • Why not print x, x+a, for each loop iteration so that you can see what's going on ? – Paul R Nov 07 '12 at 19:30
  • What are you trying to achieve exactly? Maybe [this question](http://stackoverflow.com/questions/2425251/how-do-i-get-real-integer-overflows-in-matlab-octave) helps... – Eitan T Nov 07 '12 at 19:33

3 Answers3

9

The answer is eps(a)/2.

eps is the difference to the next floating point number, so if you add half or less than that to a float, it won't change. For example:

100+eps(100)/2==100
ans =
     1

%# divide by less than two
100+eps(100)/1.9==100
ans =
     0

%# what is that number x?
eps(100)/2
ans =
   7.1054e-15

If you don't want to rely on eps, you can calculate the number as

2^(-53+floor(log2(a)))
Jonas
  • 74,690
  • 10
  • 137
  • 177
  • @iz:If you want to do this with a loop, take `2^(-i+floor(log2(a))` and increment `i` until `a+x==a` becomes true. Most likely, the iteration will stop at `i==53`. – Jonas Nov 07 '12 at 19:51
  • @iz: alternatively, start with `x==a` and divide `a` by two until you're done – Jonas Nov 07 '12 at 19:52
  • @iz: instead of starting with `a`, you should actually start with `2^(floor(log2(a))`. Then you'll end up with the same result. eps(a) returns a power of two, and if `a` isn't a power of two, you will get a slightly different result. – Jonas Nov 07 '12 at 20:45
  • @iz: `floor` rounds down. `log2` takes the logarithm to the base 2. Thus `2^floor(log2(a))` is the largest power of 2 that is smaller than `a`. – Jonas Nov 07 '12 at 20:58
  • @iz: No. It would be, for x+1000==1000, `x=2^(floor(log2(1000)));while (x+1000)~=1000,x=x/2;end` – Jonas Nov 07 '12 at 21:38
  • @iz: sure, just swap x and a and decrease the smaller number. If you keep increasing the large number, the small number will satisfy the "equality" for the increased large number, not the original large number. – Jonas Nov 07 '12 at 23:18
1

You're small algorithm is certainly not correct. The only conditions where A = X + A are when X is equal to 0. By default matlab data types are doubles with 64 bits.

Lets pretend that matlab were instead using 8 bit integers. The only way to satisfy the equation A = X + A is for X to have the binary representation of [0 0 0 0 0 0 0 0]. So any number between 1 and 0 would work as decimal points are truncated from integers. So again if you were using integers A = A + X would resolve to true if you were to set the value of X to any value between [0,1). However this value is meaningless because X would not take on this value but rather it would take on the value of 0.

It sounds like you are trying to find the resolution of matlab data types. See this: http://www.mathworks.com/help/matlab/matlab_prog/floating-point-numbers.html

slayton
  • 20,123
  • 10
  • 60
  • 89
0

The correct answer is that, provided by Jonas: 0.5 * eps(a)

Here is an alternative for the empirical and approximate solution:

>> a = 2184;
>> e = 2 .^ (-100 : 100); % logarithmic scale
>> idx = find(a + e == a, 1, 'last')

idx =

    59

>> e(idx)

ans =

  2.2737e-013
Serg
  • 13,470
  • 8
  • 36
  • 47