On 25-Apr-2007, David Grohmann wrote:
| John W. Eaton wrote:
| > On 25-Apr-2007, David Grohmann wrote:
| >
| > | I know octave doesnt support single precision floats very well, but is
| > | this a bug or to be expected? is there a workaround?
| > | (why doesn't x == y ?) :
| > |
| > | octave:28> [fid, msg]=fopen('mytest.out', 'w')
| > | fid = 64
| > | msg =
| > | octave:29> x = 0.4
| > | x = 0.400000000000000
| > | octave:30> fwrite( fid, x, 'float32' )
| > | ans = 1
| > | octave:31> fclose(fid)
| > | ans = 0
| > | octave:32> [fid, msg]=fopen('mytest.out', 'r')
| > | fid = 64
| > | msg =
| > | octave:33> y = fread(fid, 1, 'float32' )
| > | y = 0.400000005960464
| > | octave:35> fclose(fid)
| >
| > You read a 32-bit float into a 64-bit value. Octave (actually the C
| > library I/O system) is printing more digits than can be represented
| > exactly (2/5 is not exactly represented by a binary floating point
| > value).
| >
| > jwe
| >
| Are you saying it is just a display problem?
I don't consider it a bug.
| octave:36> isequal(x,y)
| ans = 0
These aren't equal because
x = 0.4
gives you a 64-bit approximation of 2/5, which does not have an exact
binary floating point representation. By saving this value as a
32-bit float and reading it back, you lost some information.
Try this:
fid = fopen ("foo.out", "w");
x = 0.40000;
fwrite (fid, x, 'float32');
fclose (fid);
fid = fopen ("foo.out", "r");
y = fread (fid, 1, "float32");
format bit
x
y
I see
x = 0011111111011001100110011001100110011001100110011001100110011010
y = 0011111111011001100110011001100110100000000000000000000000000000
Note the string of zeros that shows the loss of precision. You
changed the representation by writing and reading using a 32-bit
floating point representation. What did you expect?
jwe