2014-01-11 5 views
0

Я пишу метод, который вычисляет уравнение 2D линии в виде a*x+b*y=1с плавающей точкой точность

//Given two points, find the equation of the line by solving two linear equations and then test the result. (For simplicity, assume that delta !=0 here) 

private boolean solveAndRetry(float x1,float y1, float x2,float y2) { 
     float delta = x1 * y2 - x2 * y1; 
     float deltaA = y2 - y1; 
     float deltaB = x1 - x2; 

     float a = deltaA/delta; 
     float b = deltaB/delta; 
     float c = 1; 

     //test 
     if (a * x2 + b * y2 == c) { 
     System.out.println("ok"); 
      return true; 
     } 
     else { 
      System.out.println(a * x2 + b * y2-c); 
      return false; 
     } 
    } 

Когда я бежал, я ожидал, что там будет все «ОК» s, но это не так и я не знаю, почему

public static void main(String[] args) { 
     for (float x = 0; x < 10; x += 0.01f) { 
      solveAndRetry(1, -1, x, 2); 
     } 
    } 

Вот некоторые строки в результате

ok 
ok 
ok 
ok 
ok 
ok 
ok 
ok 
-5.9604645E-8 
ok 
-5.9604645E-8 
ok 
ok 
ok 
1.1920929E-7 
ok 
ok 
-5.9604645E-8 
ok 
+2

[Что каждый компьютерный ученый должен знать о плавающей точке] (http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) –

+1

Также: http: //www.cygnus- software.com/papers/comparingfloats/comparingfloats.htm –

ответ

3

float имеет точность от 6 до 7 десятичных цифр. Поскольку ошибок округления нельзя избежать, ваши результаты так же хороши, как и могут.

Как правило, вы никогда не сравнили числа с плавающей запятой для равенства. Вместо x == y всегда использовать сравнение с интервалом:

Math.abs(x - y) < eps 

при правильном выборе ЭПС.

+0

Я согласен, но вы думаете, что изменение типа на десятичный или Bigdecimal изменит что-нибудь? –

+1

@ яша не в принципе. Вы можете получить больше точности, но есть еще реальные цифры, которые невозможно точно представить. – Henry

+0

Кроме того, вы можете увеличить точность, используя double вместо float. Но это не помешает вам округлить ошибки, как показано. – isnot2bad

Смежные вопросы