it is very funny fact. We can generalize it a bit by using an arbitrary number of nested absolute value. Here is my function :

function zout = fun_abs(x,y,a,n,b)

xtmp = abs(x);

for i1 = 1:n-1

xtmp = abs(xtmp+a);

end

ytmp = abs(y);

for i1 = 1:n-1

ytmp = abs(ytmp+a);

end

zout = abs( xtmp – ytmp ) >= b;

In the example of the post we have n=3, a=-1 and b=1/3.

]]>- the flag ‘f’ returns the exact representation of the floating point number, as-is, without any approximation. Obviously the precision is limited by the original data type of the floating-point number (32-bits for singles and 64-bites for doubles)

– the flag ‘r’ (the default one) will try to be smart and compensate for existing round-off error to get a “nicely expressed’ number (“nice” being of the supported forms of p/q, p*pi/q, sqrt(p), 2^q, 10^q with integers p and q).

– the flag ‘e’ will return the same thing as ‘r’ in addition to the difference between that and the exact ‘f’ representation, where the estimation error is expressed in “eps” machine epsilon.

– the flag ‘d’ will take the exact ‘f’ representation and “round it” to the specified number of digits taken from the current “digits()” function value. In other words sym(x,’d’) is equivalent to vpa(sym(x,’f’),digits())

___

To confirm my understanding of the ‘f’ flag option, I tried it manually with the example you gave:

>> t = 0.1

>> fprintf(‘%bx’, t)

3fb999999999999a

Next we convert the hex notation to binary:

% the 64-bit double-precision floating-point representation of one-tenth

0 01111111011 1001100110011001100110011001100110011001100110011010

We separate the sign, exponent, and fraction parts and store them as bit vectors:

sign = 0

exponent = ‘01111111011’ – ‘0’

fraction = ‘1001100110011001100110011001100110011001100110011010’ – ‘0’

Now we compute the real value they represent (according to the definition of the IEEE 754 format):

% (here I’m only using SYM to keep the numbers expressed as quotients)

>> x = …

(-1)^(sign) * …

2^(sum(exponent .* (2.^sym(10:-1:0))) – 1023) * …

(1 + sum(fraction .* (2.^sym(-(1:52)))))

and we get the same thing returned by the SYM function with the ‘f’ flag:

>> x

x =

3602879701896397/36028797018963968

>> sym(t, ‘f’)

ans =

3602879701896397/36028797018963968

___

By the way, I think there is a typo in the documentation of SYM function regarding the ‘f’ flag. It says:

f stands for “floating-point.” All values are represented in the form N*2^e or -N*2^e, where N and e are integers, N >= 0. […]

Isn’t N supposed to be a *rational number* not an *integer*? (still non-negative of course).

]]>An example

>> t = .1

t =

0.1000

>> sym(t)

ans =

1/10

>> sym(t,’f’)

ans =

3602879701896397/36028797018963968

>> sym(t,’e’)

ans =

eps/40 + 1/10

>> sym(t,’r’)

ans =

1/10

>> sym(t,’d’)

ans =

0.10000000000000000555111512312578

Use ‘f’ if you want an exact conversion, avoiding sym’s trickery. Use ‘d’ with vpa. Use ‘e’ if you want to see floating point approximations expressed in terms of eps. Use ‘r’ to get an aggressive form of sym’s tricks, or maybe it’s just the same as sym without a flag, I forget.

— Cleve

I put explicit details (including code, output, and explanation) at

http://www.hbeLabs.com/lshape/index.html

that demonstrates clearly how to obtain the 150 digits or more. (I’m still making small edits, but it seems close

to what I want to say.)

Perhaps someone can reproduce it in matlab? Have a lot of fun!

–Bob Jones ]]>