Почему результат 1/3 == 0?



я писал этот код:



public static void main(String[] args) {
double g = 1 / 3;
System.out.printf("%.2f", g);
}


результат 0. Почему это, и как мне решить эту проблему?

422   13  

13 ответов:

два операнда (1 и 3) являются целыми числами, поэтому используется целочисленная арифметика (деление здесь). Объявление переменной результата как double просто приводит к неявному преобразованиюпосле раздела.

целочисленное деление, конечно, возвращает истинный результат деления округляется в сторону нуля. Результат округляется до 0 здесь. (Обратите внимание, что процессор на самом деле не делает никакого округления, но вы можете думать об этом так до сих пор.)

кроме того, обратите внимание, что если и операнды (числа) задаются как поплавки; 3.0 и 1.0, или даже просто первый, затем используется арифметика с плавающей запятой, давая вам 0.333....

1/3 использует целочисленное деление, так как обе стороны являются целыми числами.

вам нужно, чтобы хотя бы один из них был float или double.

если вы вводите значения в исходном коде, как ваш вопрос, вы можете сделать 1.0/3; the 1.0 двойной.

если вы получаете значения из других источников вы можете использовать (double) в свою очередь int на double.

int x = ...;
int y = ...;
double value = ((double) x) / y;

явно приведите его как double

double g = 1.0/3.0

это происходит потому, что Java использует операцию целочисленного деления для 1 и 3 так как вы ввели их в качестве констант.

вы должны использовать

double g=1.0/3;

или

double g=1/3.0;

целочисленное деление возвращает целое число.

потому что вы делаете целочисленное деление.

как говорит @Noldorin, если оба оператора являются целыми числами, то используется целочисленное деление.

результат 0.33333333 не может быть представлен в виде целого числа, поэтому только целая часть (0) присваивается результату.

Если любой из операторов double/float, затем чисел с плавающей запятой будет иметь место. Но у вас будет такая же проблема, если вы это сделаете:

int n = 1.0 / 3.0;

потому что он обрабатывает 1 и 3 как целые числа, поэтому округление результата до 0, так что это целое число.

чтобы получить результат, который вы ищете, явно сообщите java, что числа удваиваются следующим образом:

double g = 1.0/3.0;

сделать 1 поплавок и поплавок разделение будет использоваться

public static void main(String d[]){
    double g=1f/3;
    System.out.printf("%.2f",g);
}

преобразование в Java довольно просто, но нужно некоторое понимание. Как объясняют в JLS для целочисленных операций:

если целочисленный оператор, отличный от оператора сдвига, имеет хотя бы один операнд типа long, то операция выполняется с использованием 64-разрядной точности, а результат числового оператора имеет тип long. Если другой операнд не длинен, он сначала расширяется (§5.1.5), чтобы ввести long числовым продвижением (§5.6).

и пример всегда лучший способ перевести JLS ;)

int + long -> long
int(1) + long(2) + int(3) -> long(1+2) + long(3)

в противном случае операция выполняется с использованием 32-разрядной точности, а результат числового оператора имеет тип int. Если какой-либо операнд не является int, он сначала расширяется до типа int с помощью числового продвижения.

short + int -> int + int -> int

небольшой пример использования Eclipse, чтобы показать, что даже добавление двух short s не будет так просто :

short s = 1;
s = s + s; <- Compiling error

//possible loss of precision
//  required: short
//  found:    int

это потребует литья с возможной потерей точности.

то же самое верно для операторы с плавающей запятой

если хотя бы один из операндов числового оператора имеет тип double, то операция выполняется с использованием 64-разрядной арифметики с плавающей запятой, а результатом числового оператора является значение типа double. Если другой операнд не является двойным, он сначала расширяется (§5.1.5) до введите double by numeric promotion (§5.6).

так промотирование сделано на поплавке в двойник.

и сочетание целочисленного и плавающего значения приводит к плавающим значениям, как сказано

если хотя бы один из операндов двоичного оператора имеет тип с плавающей запятой, то операция является операцией с плавающей запятой, даже если другой является целым.

это верно для бинарных операторов, но не для "назначения Операторы " нравится +=

достаточно простого рабочего примера, чтобы доказать это

int i = 1;
i += 1.5f;

причина в том, что здесь выполняется неявное приведение, это будет выполняться как

i = (int) i + 1.5f
i = (int) 2.5f
i = 2

(1/3) означает целочисленное деление, поэтому вы не можете получить десятичное значение из этого подразделения. Для решения этой проблемы используйте:

public static void main(String[] args) {
        double g = 1.0 / 3;
        System.out.printf("%.2f", g);
    }

1 и 3-целые константы и так и Java целочисленное деление, которое результат 0. Если вы хотите написать двойные константы, вы должны написать 1.0 и 3.0.

вместо этого сделайте "double g=1.0 / 3.0;".

многие другие не смогли указать на реальную проблему:

операция только над целыми числами приводит результат операции к целому числу.

Это обязательно означает, что результаты с плавающей точкой, что может отображается как целое число, будет усечено (отрежьте десятичную часть).

Что это литье (typecasting / type conversion) вы спрашиваете?

Это зависит от реализации язык, но Википедия имеет довольно полное представление, и это говорит о принуждение а также, что является ключевым элементом информации в ответе на ваш вопрос.

http://en.wikipedia.org/wiki/Type_conversion

public static void main(String[] args) {
    double g = 1 / 3;
    System.out.printf("%.2f", g);
}

Так как и 1 и 3 являются ints результат не округляется, но он усекается. Поэтому вы игнорируете дроби и берете только целые.

чтобы избежать этого, имейте по крайней мере одно из ваших чисел 1 или 3 в виде десятичной формы 1.0 и/или 3.0.

Comments

    Ничего не найдено.