Странный модуль Java

Пишу код для тестирования методов, отображения еды и цены:

import java.util.Scanner;
public class JavaTutorial5Class {

        public static void main(String[] args)
        {
            greeting("Thunderdome");
            prices("Fatburger", 7.50);
        }
        static void greeting(String restaurant)
        {
            System.out.println("Welcome to "  + restaurant);
        }

        static void prices(String burger, double price){
            System.out.print(burger + " is " + "$" + price);
            //System.out.println(Math.ceil(price % 10));
            if (Math.ceil(price % 10) == 8.0){
                System.out.print("0");
            }
        }
    }

Почему price % 10 == 8.0? И это действительно то, что вам нужно сделать, чтобы получить хвост 0 там?

РЕДАКТИРОВАТЬ: все, что этот код должен делать, это печатать «Fatburger is $7,50», проблема в том, что простое указание ему аргумента 7,50 преобразует его в 7,5.


person user1159454    schedule 10.09.2012    source источник
comment
Что должен делать код? это не имеет большого смысла.   -  person SJuan76    schedule 10.09.2012
comment
Это предупреждение о том, как работает оператор остаток (обратите внимание, что это не оператор модуль).   -  person obataku    schedule 10.09.2012
comment
Обратился к тому, что он должен делать... и я подумал, что это оператор модуля... какая разница?   -  person user1159454    schedule 10.09.2012
comment
Возможно, лучше было бы задать вопрос: как мне напечатать двойные числа ровно с двумя цифрами после запятой? Я не очень разбираюсь в java, но, конечно же, есть несколько хороших операций форматирования строк, которые могут печатать цены, не заставляя вас использовать %   -  person Kevin    schedule 10.09.2012
comment
@Кевин правильно; он должен использовать System.out.printf для этого.   -  person obataku    schedule 10.09.2012


Ответы (5)


В этом коде причина, по которой вы получаете 8.0, связана с тем, что вы используете Math.ceil.

7.5 % 10 это 7.5, а Math.ceil(7.5) это 8.0.

Однако, и это то, что встречается очень часто и является очень распространенной ошибкой для новичков... цены почти никогда не должны храниться как двойные. Двойная арифметика не всегда так точна, как можно было бы ожидать, в основном из-за того, как на самом деле хранятся двойные числа. Например, рассмотрите это:

double sum = 0.0;
int n = 6;
for (int i = 0; i < n; i++) {
    sum += 1.0 / n;
}
System.out.println(sum);

Вы ожидаете, что он выведет 1.0, но на самом деле выводит 0.9999999999999999

Правильный способ обработки цен — две int: одна для долларов, другая для центов.

person Joe K    schedule 10.09.2012
comment
Спасибо, я честно не знаю, что делаю с двойниками, я просто слежу за тем, что пишет парень. Раньше я не думал о том, чтобы разделить доллары и центы, хорошая идея. - person user1159454; 10.09.2012
comment
Или еще проще: используйте bigdecimal. - person assylias; 11.09.2012

Попробуйте это вместо этого:

static void prices(String burger, double price){
    System.out.print(burger + " is $" + price);
    if ((int)(price * 10) == price * 10)
        System.out.print(0);
}

Как у вас сейчас, 7.5 % 10 просто возвращает 7.5, а Math.ceil округляет это число до 8.0.

person arshajii    schedule 10.09.2012

цена % 10 на самом деле 7,5. Модуль — это остаток от деления (или сколько раз одно число может вписаться в другое). Например, 22 % 10 равно 2, поскольку 10 может дважды вписаться в 22, не переходя при этом. Взяв потолок, который поднимает его до ближайшего целого числа, увеличивая 7,5 до 8. Следовательно, оператор if становится истинным.

person Eddie D    schedule 10.09.2012

Я думаю, что в конечном итоге решение, которое он хочет (напечатать двойник в виде валюты), может быть решено так...

Добавить импорт

import java.text.NumberFormat;  

и используйте этот код

NumberFormat nf = NumberFormat.getCurrencyInstance(); 
System.out.print(burger + " is " + "$" + nf.format(price));

Забудьте обо всех модулях (это слишком сложный и неправильный способ добиться того, о чем вы просите).

Также есть небольшая проблема с округлением с удвоением, и если вам нужна идеальная точность (сомнительно, учитывая остальную часть вашего кода), но обычно стандартом является использование 2 целых чисел для хранения валюты).

person Kevin DiTraglia    schedule 10.09.2012

Используйте следующую команду для правильного форматирования строки:

System.out.printf(%s is $%.2f, burger, price)

На этой странице можно найти руководство по форматированию строк: http://www.homeandlearn.co.uk/java/java_formatted_strings.html

%s будет заменено значением burger, отформатированным как строка.
%.2f будет заменено значением price, отформатированным как десятичное число с двумя знаками после запятой.

person bfishman    schedule 10.09.2012