octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: A problem with range objects and floating point numbers


From: s.jo
Subject: Re: A problem with range objects and floating point numbers
Date: Tue, 23 Sep 2014 08:28:37 -0700 (PDT)

Oliver Heimlich wrote
> Am 23.09.2014 03:27, schrieb s.jo:
>> John W. Eaton wrote
>>> On 06/20/2014 04:28 PM, Julien Bect wrote:
>>>> Hello all,
>>>>
>>>> I would like to bring the following bug report to your attention :
>>>>
>>>> http://savannah.gnu.org/bugs/?42589
>>>>
>>>> A simple example of the regression described in this report is the
>>>> following :
>>>>
>>>>      octave:1> (9:10) * .1 - 1
>>>>      ans =
>>>>
>>>>         -1.0000e-01    2.7756e-17
>>>>
>>>> The second element should be 0.
>>>>
>>>> Rik thinks that this bug might be hard to solve... which is why I'm
>>>> bringing this up on this list :)
>>>
>>> Please see my comments on the bug tracker.
>>>
>>> jwe
>> 
>> I have the similar problem with octave 3.8.1 on cygwin.
>> See below:
>> octave:50> t=[-2:0.1:0]
>> t =
>> 
>>  Columns 1 through 5:
>> 
>>                     -2                  -1.9                  -1.8           
>>       
>> -1.7                  -1.6
>> 
>>  Columns 6 through 10:
>> 
>>                   -1.5                  -1.4                  -1.3           
>>       
>> -1.2                  -1.1
>> 
>>  Columns 11 through 15:
>> 
>>                     -1                  -0.9                  -0.8           
>>       
>> -0.7                  -0.6
>> 
>>  Columns 16 through 20:
>> 
>>                   -0.5                  -0.4                  -0.3           
>>       
>> -0.2   -0.0999999999999999
>> 
>>  Column 21:
>> 
>>                      0
>> 
>> Range command is not good with floating-point step only starting from
>> negative integer as above.
>> 
>> I am trying to upgrade octave 3.8.2 to see if this problem is fixed.
>> 
>> I post it just in case.
> 
> The results are perfectly okay. This is how floating point works, see
> IEEE 754. Above mentioned bug report also gives some explanation in the
> comments.
> 
> The “problem” occurs because .1 is not a binary floating point number.
> and the approximation
> 0.1000000000000000055511151231257827021181583404541015625 is used
> instead. 10 * 0.1 suffers (or in this case benefits) from rounding.
> 
> In the last example with t=[-2:0.1:0] only the numbers -2, -1.5, -1,
> -0.5, and 0 have the exact value that is displayed. Column 20
> additionally yields a propagation of errors. You can check this with the
> bit format:
> 
> octave:3> format bit
> octave:4> -.1
> ans = 1011111110111001100110011001100110011001100110011001100110011010
> (this is -0.1000000000000000055511151231257827021181583404541015625)
> 
> octave:5> -2 + 19 * .1
> ans = 1011111110111001100110011001100110011001100110011001100110010000
> (this is -0.09999999999999997779553950749686919152736663818359375)
> 
> octave:6> t(20)
> ans = 1011111110111001100110011001100110011001100110011001100110010000

Thanks to your comments, I understand what happened in the range operator
with floating-point numbers.
Also I found that most people use the linspace function to generate
floating-point squences.

I check and compare colon operator and linspace function: (octave 3.8.2 on
cygwin)

%%
% setup
fp_start=-2;
fp_end=1;
fp_step=0.1;
fp_num=fix(abs(fp_end-fp_start)/fp_step)+1;
% range operator (floating-point)
t1=(fp_start:fp_step:fp_end);
% linspace function
t2=linspace(fp_start,fp_end,fp_num);
% compare
format long e
[t1' t2']
format bit
[t1' t2']

%% results:

ans =

  -2.00000000000000e+00  -2.00000000000000e+00
  -1.90000000000000e+00  -1.90000000000000e+00
  -1.80000000000000e+00  -1.80000000000000e+00
  -1.70000000000000e+00  -1.70000000000000e+00
  -1.60000000000000e+00  -1.60000000000000e+00
  -1.50000000000000e+00  -1.50000000000000e+00
  -1.40000000000000e+00  -1.40000000000000e+00
  -1.30000000000000e+00  -1.30000000000000e+00
  -1.20000000000000e+00  -1.20000000000000e+00
  -1.10000000000000e+00  -1.10000000000000e+00
  -1.00000000000000e+00  -1.00000000000000e+00
  -9.00000000000000e-01  -9.00000000000000e-01
  -8.00000000000000e-01  -8.00000000000000e-01
  -7.00000000000000e-01  -7.00000000000000e-01
  -6.00000000000000e-01  -6.00000000000000e-01
  -5.00000000000000e-01  -5.00000000000000e-01
  -4.00000000000000e-01  -4.00000000000000e-01
  -3.00000000000000e-01  -3.00000000000000e-01
  -2.00000000000000e-01  -2.00000000000000e-01
  -9.99999999999999e-02  -1.00000000000000e-01
   1.11022302462516e-16   0.00000000000000e+00
   1.00000000000000e-01   1.00000000000000e-01
   2.00000000000000e-01   2.00000000000000e-01
   3.00000000000000e-01   3.00000000000000e-01
   4.00000000000000e-01   4.00000000000000e-01
   5.00000000000000e-01   5.00000000000000e-01
   6.00000000000000e-01   6.00000000000000e-01
   7.00000000000000e-01   7.00000000000000e-01
   8.00000000000000e-01   8.00000000000000e-01
   9.00000000000000e-01   9.00000000000000e-01
   1.00000000000000e+00   1.00000000000000e+00

ans =

 Column 1:

  1100000000000000000000000000000000000000000000000000000000000000
  1011111111111110011001100110011001100110011001100110011001100110
  1011111111111100110011001100110011001100110011001100110011001101
  1011111111111011001100110011001100110011001100110011001100110011
  1011111111111001100110011001100110011001100110011001100110011010
  1011111111111000000000000000000000000000000000000000000000000000
  1011111111110110011001100110011001100110011001100110011001100110
  1011111111110100110011001100110011001100110011001100110011001101
  1011111111110011001100110011001100110011001100110011001100110011
  1011111111110001100110011001100110011001100110011001100110011001
  1011111111110000000000000000000000000000000000000000000000000000
  1011111111101100110011001100110011001100110011001100110011001100
  1011111111101001100110011001100110011001100110011001100110011001
  1011111111100110011001100110011001100110011001100110011001100110
  1011111111100011001100110011001100110011001100110011001100110010
  1011111111011111111111111111111111111111111111111111111111111110
  1011111111011001100110011001100110011001100110011001100110011000
  1011111111010011001100110011001100110011001100110011001100110010
  1011111111001001100110011001100110011001100110011001100110010110
  1011111110111001100110011001100110011001100110011001100110010010
  0011110010100000000000000000000000000000000000000000000000000000
  0011111110111001100110011001100110011001100110011001100110100010
  0011111111001001100110011001100110011001100110011001100110011110
  0011111111010011001100110011001100110011001100110011001100110110
  0011111111011001100110011001100110011001100110011001100110011100
  0011111111100000000000000000000000000000000000000000000000000001
  0011111111100011001100110011001100110011001100110011001100110100
  0011111111100110011001100110011001100110011001100110011001101000
  0011111111101001100110011001100110011001100110011001100110011011
  0011111111101100110011001100110011001100110011001100110011001110
  0011111111110000000000000000000000000000000000000000000000000000

 Column 2:

  1100000000000000000000000000000000000000000000000000000000000000
  1011111111111110011001100110011001100110011001100110011001100110
  1011111111111100110011001100110011001100110011001100110011001101
  1011111111111011001100110011001100110011001100110011001100110011
  1011111111111001100110011001100110011001100110011001100110011010
  1011111111111000000000000000000000000000000000000000000000000000
  1011111111110110011001100110011001100110011001100110011001100110
  1011111111110100110011001100110011001100110011001100110011001101
  1011111111110011001100110011001100110011001100110011001100110011
  1011111111110001100110011001100110011001100110011001100110011010
  1011111111110000000000000000000000000000000000000000000000000000
  1011111111101100110011001100110011001100110011001100110011001101
  1011111111101001100110011001100110011001100110011001100110011010
  1011111111100110011001100110011001100110011001100110011001100110
  1011111111100011001100110011001100110011001100110011001100110011
  1011111111100000000000000000000000000000000000000000000000000000
  1011111111011001100110011001100110011001100110011001100110011010
  1011111111010011001100110011001100110011001100110011001100110011
  1011111111001001100110011001100110011001100110011001100110011010
  1011111110111001100110011001100110011001100110011001100110011010
  0000000000000000000000000000000000000000000000000000000000000000
  0011111110111001100110011001100110011001100110011001100110011010
  0011111111001001100110011001100110011001100110011001100110011010
  0011111111010011001100110011001100110011001100110011001100110011
  0011111111011001100110011001100110011001100110011001100110011010
  0011111111100000000000000000000000000000000000000000000000000000
  0011111111100011001100110011001100110011001100110011001100110011
  0011111111100110011001100110011001100110011001100110011001100110
  0011111111101001100110011001100110011001100110011001100110011010
  0011111111101100110011001100110011001100110011001100110011001101
  0011111111110000000000000000000000000000000000000000000000000000

The colon operator works well with integers, of course.
With floating-point numbers, it happens to show floating-point
representation errors.
Most worst thing is that the locations of such errors is not consistent, not
predictable.
Try format long e; (-10:0.1:1)' and (-2:0.1:1)'.
You can see the errors are close to -0 side, but the total number and the
locations
are different according to the starting number of range operator.

I think that people use the range operator with floating-point numbers to
simulate their work and share it other people most of case.  Such
inconsistency of floating-point range operator may mislead their result.

Thus, the implementation of the floating-point case colon operator should be
changed to use the linspace function or equivalent, I guess.

I agree that it is not a bug of colon operator. It is a nature behavior.
But, people does not want to see floating-point number's weird behaviors in
their application.
People usually expect the equally spaced numbers when they use colon
operators.

Mathlab does not show such behavior at least with 'format long e'. I need to
check the raw bit format.
I guess that they use linspace or similar in colon operator.

-- jo.

ps. see...
octave:171> (-10:0.1:1)'
ans =

  -1.00000000000000e+01
  -9.90000000000000e+00
  -9.80000000000000e+00
  -9.70000000000000e+00
  -9.60000000000000e+00
  -9.50000000000000e+00
  -9.40000000000000e+00
  -9.30000000000000e+00
  -9.20000000000000e+00
  -9.10000000000000e+00
  -9.00000000000000e+00
  -8.90000000000000e+00
  -8.80000000000000e+00
  -8.70000000000000e+00
[[[snip]]]
  -1.60000000000000e+00
  -1.50000000000000e+00
  -1.40000000000000e+00
  -1.30000000000000e+00
  -1.20000000000000e+00
  -1.10000000000000e+00
  -1.00000000000000e+00
  -8.99999999999999e-01
  -7.99999999999999e-01
  -7.00000000000000e-01
  -5.99999999999999e-01
  -4.99999999999999e-01
  -3.99999999999999e-01
  -2.99999999999999e-01
  -1.99999999999999e-01
  -9.99999999999995e-02
   5.55111512312578e-16
   1.00000000000001e-01
   2.00000000000001e-01
   3.00000000000001e-01
   4.00000000000001e-01
   5.00000000000001e-01
   6.00000000000001e-01
   7.00000000000001e-01
   8.00000000000001e-01
   9.00000000000001e-01
   1.00000000000000e+00






--
View this message in context: 
http://octave.1599824.n4.nabble.com/A-problem-with-range-objects-and-floating-point-numbers-tp4664900p4666662.html
Sent from the Octave - Maintainers mailing list archive at Nabble.com.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]