Jak sprawić, by dzielenie 2 intów tworzyło zmiennoprzecinkową zamiast kolejnej liczby int?


149

W innym ćwiczeniu Bruce'a Eckelsa polegającym na obliczaniu prędkości, v = s / tgdzie s i t są liczbami całkowitymi. Jak to zrobić, aby podział wykręcił pływak?

class CalcV {
  float v;
  float calcV(int s, int t) {
    v = s / t;
    return v;
  } //end calcV
}

public class PassObject {

  public static void main (String[] args ) {
    int distance;
    distance = 4;

    int t;
    t = 3;

    float outV;

    CalcV v = new CalcV();
    outV = v.calcV(distance, t);

    System.out.println("velocity : " + outV);
  } //end main
}//end class

float v = s / t wykonuje dzielenie, a następnie przekształca wynik w float. float v = (float) s / t rzuca na float, a następnie wykonuje dzielenie.
Juan Carlos Iturriagagoitia

Odpowiedzi:


307

Po prostu rzuć najpierw jeden z dwóch operandów na zmiennoprzecinkowy.

v = (float)s / t;

Obsada ma wyższy priorytet niż podział, więc dzieje się to przed podziałem.

Drugi operand zostanie efektywnie automatycznie rzutowany na zmiennoprzecinkowy przez kompilator, ponieważ reguły mówią, że jeśli którykolwiek z operandów jest typu zmiennoprzecinkowego, operacja będzie operacją zmiennoprzecinkową, nawet jeśli drugi operand jest całkowity. Specyfikacja języka Java, §4.2.4 i §15.17


8
Grrr, zajęło mi to około 30 minut, zanim to znalazłem i rozgryzłem. Tak prosty. : D
Rihards

Mówiąc dokładniej, wspomniano tutaj o tej konkretnej zasadzie: operatory multiplikatywne , więc pozwólmy jej stać tutaj na przyszłość.
kwantowy


13

Próbować:

v = (float)s / (float)t;

Rzutowanie int na zmiennoprzecinkowe pozwoli na podział zmiennoprzecinkowy.

Jednak naprawdę wystarczy rzucić jedną.


Nie wiem, to tak, jakby powiedzieć, że zamiast iof ints należy używać longs.
Jakub Zaverka

4

Rzuć jedną z liczb całkowitych na liczbę zmiennoprzecinkową, aby wymusić wykonanie operacji za pomocą matematyki zmiennoprzecinkowej. W przeciwnym razie zawsze preferowana jest matematyka liczb całkowitych. Więc:

v = (float)s / t;



3

Możesz rzucić nawet tylko jedną z nich, ale dla spójności możesz chcieć jawnie rzutować oba, więc powinno działać coś takiego jak v = (float) s / (float) t.


1

Standard JLS

JLS 7 15.17.2. Operator działu / mówi:

Dzielenie liczb całkowitych zaokrągla się w kierunku 0. Oznacza to, że iloraz utworzony dla operandów n i d, które są liczbami całkowitymi po binarnej promocji liczbowej (§5.6.2), jest wartością całkowitą q, której wielkość jest tak duża, jak to możliwe, spełniając | d · q | ≤ | n |. Ponadto q jest dodatnie, gdy | n | ≥ | d | oraz n i d mają ten sam znak, ale q jest ujemne, gdy | n | ≥ | d | oraz n i d mają przeciwne znaki.

Dlatego 1/2nie daje pływaka.

Konwersja tylko jednego z nich na float, jak w przykładzie, (float)1/2wystarczy, ponieważ 15.17. Operatory multiplikatywne mówi:

Binarna promocja liczbowa jest wykonywana na operandach

i 5.6.2. Binarna promocja numeryczna mówi:

  • Jeśli jeden z operandów jest typu double, drugi jest konwertowany na double.
  • W przeciwnym razie, jeśli jeden z operandów jest typu float, drugi jest konwertowany na float

0

Rzuć jedną z liczb całkowitych / obie liczby całkowite na zmiennoprzecinkowe, aby wymusić wykonanie operacji za pomocą funkcji Matematyka zmiennoprzecinkowa. W przeciwnym razie preferowana jest matematyka liczb całkowitych. Więc:

1. v = (float)s / t;
2. v = (float)s / (float)t;

0

Spróbuj tego:

class CalcV 
{
      float v;
      float calcV(int s, int t)
      {
          float value1=s;
          float value2=t;
          v = value1 / value2;
          return v;
      } //end calcV
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.