Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > глюк с числами с плав. запятой


Автор: ZAVS 19.11.2004, 00:02
привет Всем

вот кусок программы
Код


[code=java]
  double a=0;
   double b=0.2;
   
   for(int i=0;i<=30;i++){
     ++a;
     if(i%3==0){
       a+=b;
     }
     System.out.println("a"+i+": "+a);
   }



а вот результат

Цитата

a0: 1.2
a1: 2.2
a2: 3.2
a3: 4.4
a4: 5.4
a5: 6.4
a6: 7.6000000000000005
a7: 8.600000000000001
a8: 9.600000000000001
a9: 10.8
a10: 11.8
a11: 12.8
a12: 14.0
a13: 15.0
a14: 16.0
a15: 17.2
a16: 18.2
a17: 19.2
a18: 20.4
a19: 21.4
a20: 22.4
a21: 23.599999999999998
a22: 24.599999999999998
a23: 25.599999999999998
a24: 26.799999999999997
a25: 27.799999999999997
a26: 28.799999999999997
a27: 29.999999999999996
a28: 30.999999999999996
a29: 31.999999999999996
a30: 33.2



кто может обяснить от чего это происходит (может в sun-е что то упустили)??
и как от этого избавиться????

Автор: Domestic Cat 19.11.2004, 01:00
Почитай кak флоат типы хранятся в памяти smile это самая обычная вещь для любогo языка.

Автор: cardinal 19.11.2004, 01:39
Цитата(ZAVS @ 18.11.2004, 23:02)
и как от этого избавиться????

округлить результаты или сделать так:
Код

 double a=0;
  double b=2;
 
  for(int i=0;i<=300;i+=10){
    a+=10;
    if(i%30==0){
      a+=b;
    }
    System.out.println("a"+i/10+": "+a/10);
  }

Автор: Domestic Cat 19.11.2004, 03:50
чтобы еще больше понять насколько плохой язык Java(шутка), можно запустить такую прогу:

Код

public class Test
{
  public static void main(String [] args)
  {
      float a = 1296856321;
      long b = 1296856301;
      long c = 1296856308;
      if (a == b) System.out.println("a==b");
      if (c == b) System.out.println("c==b");
  }
}

Автор: ElectricalStorm 19.11.2004, 18:34
тут при неявном касте присравнении
if (a == (float)b)

a = 1.29685632E9
b = 1.29685632E9

получается что они равны...;)

Автор: sergejzr 20.11.2004, 00:49
Кстати в цитате видно, как ошибки распределяются smile Чем больше числа, тем неточнее флоат smile

Автор: ZAVS 20.11.2004, 04:46
спасибо

Цитата(cardinal @ 19.11.2004, 01:39)
double a=0;
  double b=2;
 
  for(int i=0;i<=300;i+=10){
    a+=10;
    if(i%30==0){
      a+=b;
    }
    System.out.println("a"+i/10+": "+a/10);
  }




а кроме этого есть какой-то универсальный метод который позволяет избежать неточностей smile

Автор: cardinal 20.11.2004, 04:49
думаю, что все остальные способы сводятся к тому, что я уже описал или к офигительной потери эффективности...

Автор: Domestic Cat 20.11.2004, 04:54
Ну если уж очень нузна такая точность, посмотри класс BigDecimal

http://java.sun.com/j2se/1.4.2/docs/api/java/math/BigDecimal.html
Добавлено @ 04:57
Пример:

Код


   BigDecimal bd1 = new BigDecimal("123456789.0123456890");
   
   BigDecimal bd2 = BigDecimal.valueOf(123L);
   
   bd1 = bd1.add(bd2);
   bd1 = bd1.multiply(bd2);
   bd1 = bd1.subtract(bd2);
   bd1 = bd1.divide(bd2, BigDecimal.ROUND_UP);
   bd1 = bd1.negate();


Автор: Zandr 23.11.2004, 08:36
Ага java.math.BigInteger - целые, java.math.BigDecimal - вещественные, неограниченной точности.
Только расплата за это - скорость.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)