Передайте один из операндов этого целочисленного деления на & ldquo; double & rdquo; [Дубликат]

Многие многочисленные дубликаты этого вопроса задают вопрос о влиянии округления с плавающей запятой на конкретные числа. На практике легче понять, как это работает, глядя на точные результаты вычислений, а не просто на чтение. Некоторые языки предоставляют способы сделать это - например, преобразование float или double в BigDecimal в Java.

Так как это вопрос, связанный с языком, ему нужны языковые агностические инструменты, такие как как Десятичный преобразование с плавающей запятой .

Применяя его к числам в вопросе, рассматриваемым как удваивает:

0,1 преобразуется в 0,1000000000000000055511151231257827021181583404541015625,

0,2 преобразуется в 0.200000000000000011102230246251565404236316680908203125,

0,3 конвертируется в 0,29999999999999999989897769753748434595763683319091796875 и

0,30000000000000004 преобразуется в 0,3000000000000000444089209850062616169452667236328125.

Добавление первых двух чисел вручную или в десятичный калькулятор, такой как Full Precision Calculator , показывает точную сумму фактических входов: 0.3000000000000000166533453693773481063544750213623046875.

Если округлить до эквивалента 0,3, ошибка округления будет 0.0000000000000000277555756156289135105907917022705078125. Округление до эквивалента 0,30000000000000004 также дает ошибку округления 0,0000000000000000277555756156289135105907917022705078125.

Возвращаясь к конвертеру с плавающей запятой, необработанный шестнадцатеричный показатель для 0.30000000000000004 равен 3fd3333333333334, который заканчивается четной цифрой и, следовательно, является правильным результатом.

119
задан Ciro Santilli 新疆改造中心 六四事件 法轮功 15 February 2016 в 15:58
поделиться

9 ответов

Просто перенесите один из двух операндов на первый поплавок.

v = (float)s / t;

Приведение имеет более высокий приоритет, чем деление, поэтому происходит до деления.

Другой операнд будет эффективно автоматически передаваться в float компилятором, потому что правила говорят, что если любой из операндов имеет тип с плавающей точкой, то операция будет работать с плавающей запятой, даже если другой операнд является интегральным. Спецификация языка Java, §4.2.4 и §15.17

247
ответ дан Alnitak 31 August 2018 в 20:48
поделиться

Попробуйте:

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

Приведение чисел к float позволит выполнять деление с плавающей запятой.

Вам действительно нужно только набросить.

11
ответ дан anisoptera 31 August 2018 в 20:48
поделиться

Чтобы уменьшить влияние на читаемость кода, я бы предложил:

v = 1d* s/t;
4
ответ дан antyrat 31 August 2018 в 20:48
поделиться

Стандарт JLS

JLS 7 15.17.2. Оператор отдела / говорит:

Целые деления округляются до 0.

Вот почему 1/2 не дает поплавок.

Преобразование только одного для плавания, как в (float)1/2, достаточно, потому что 15.17. Мультипликативные операторы говорят:

Бинарное числовое продвижение выполняется по операндам

и 5.6.2. Двоичное числовое продвижение говорит:

  • Если любой из операндов имеет тип double, другой преобразуется в double.
  • В противном случае, если любой из операндов типа float, другой преобразуется в float
0
ответ дан Ciro Santilli 新疆改造中心 六四事件 法轮功 31 August 2018 в 20:48
поделиться

Попробуйте следующее:

class CalcV 
{
      float v;
      float calcV(int s, int t)
      {
          float value1=s;
          float value2=t;
          v = value1 / value2;
          return v;
      } //end calcV
}
0
ответ дан Floern 31 August 2018 в 20:48
поделиться

Отправляйте одно из целых чисел в float, чтобы заставить операцию выполнить с математикой с плавающей запятой. Иначе целочисленная математика всегда предпочтительна. Итак:

v = (float)s / t;
3
ответ дан Jason Coco 31 August 2018 в 20:48
поделиться

Вы можете наложить числитель или знаменатель на float ...

операции int обычно возвращают int, поэтому вам нужно изменить один из операндов.

2
ответ дан Jhonny D. Cano -Leftware- 31 August 2018 в 20:48
поделиться

Отправляйте одно из целых чисел / оба целого числа для плавания, чтобы заставить операцию выполнить с помощью математики с плавающей запятой. Иначе целочисленная математика всегда предпочтительна. Итак:

1. v = (float)s / t;
2. v = (float)s / (float)t;
0
ответ дан Nikhil Kumar 31 August 2018 в 20:48
поделиться

Вы можете наложить хотя бы один из них, но для согласованности вы можете явно указать, что должно работать как-то вроде v = (float) s / (float) t.

3
ответ дан Uri 31 August 2018 в 20:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: