Расширение или автоматическое преобразование типов в Java;почему потеря точности? - PullRequest
0 голосов
/ 14 декабря 2018

Возьмем этот код, например.

class Main {
  public static void main(String[] args) {
   int i = 41;
   long l = i*9/5;  //no explicit type casting required
   float f = i*9/5; //no explicit type casting required
   double d = i*9/5;    //no explicit type casting required
   double e = (double) i*9/5;
   System.out.println("Int value "+i);
   System.out.println("Long value "+l);
   System.out.println("Float value "+f);
   System.out.println("Double value "+d);
   System.out.println("Double value cast "+e);
  }
}

Тип цели больше, чем тип источника, и, следовательно, явное приведение не требуется, но почему потеря точности?Почему я не могу получить d и f как 73,8?

1 Ответ

0 голосов
/ 13 июня 2019

Технически то, что здесь происходит, - это не потеря точности , а использование целочисленного деления .

Давайте рассмотрим случай f: float f = i*9/5;

Поскольку операторы умножения и деления имеют одинаковый приоритет и левоассоциативны, оператор эквивалентен: float f = (i*9)/5;

Поскольку оба i=41 и 9* int -тип, тип результирующего значения также int (369).Таким образом, следующим шагом в оценке является 369/5.Поскольку тип обоих операндов - int, интерпретация оператора / заключается в использовании целочисленного деления, которое отбрасывает любой дробный остаток.Поскольку 369/5 = 73 + 4/5, выражение оценивается как 73, которое затем преобразуется в float значение 73.0 и присваивается f.

Очень похожий процесс происходит для d, за исключением того, что окончательное преобразование 73 в double значение 73.0.

Обратите внимание, что хотя я включил промежуточные шагив оценке левая ассоциативность не влияет на использование целочисленного деления.float f = i*(9/5); приводит к f = 41.0.

...