Преобразование из float в double в C #, что делает разницу [duplicate]

Я попытаюсь объяснить вам статическую вещь. Прежде всего статические переменные не принадлежат ни одному конкретному экземпляру класса. Они распознаются с именем класса. Статические методы снова не относятся к какому-либо конкретному экземпляру. Они могут получить доступ только к статическим переменным. Представьте, что вы вызываете MyClass.myMethod (), а myMethod - это статический метод. Если вы используете нестатические переменные внутри метода, как, черт возьми, он знает, какие переменные использовать? Вот почему вы можете использовать из статических методов только статические переменные. Повторяю, они НЕ принадлежат ни одному конкретному экземпляру.

77
задан plinth 27 May 2009 в 15:40
поделиться

9 ответов

105
ответ дан Jon Skeet 25 August 2018 в 04:38
поделиться

Используйте BigDecimal вместо float / double. Существует множество чисел, которые не могут быть представлены как двоичная с плавающей запятой (например, 0.1). Таким образом, вы либо должны всегда округлять результат до известной точности, либо использовать BigDecimal.

Для получения дополнительной информации см. http://en.wikipedia.org/wiki/Floating_point .

6
ответ дан Aaron Digulla 25 August 2018 в 04:38
поделиться
  • 1
    Допустим, у вас в вашем кеше есть 10-метровые торговые цены, вы все еще считаете, что используете BigDecimal и создаете уникальные возможности, скажем, ~ 6 млн. Объектов (чтобы угадать мухи / неизменные) .. или есть еще что-нибудь? – Sendi_t 27 May 2015 в 17:06
  • 2
    @Sendi_t Пожалуйста, не используйте комментарии, чтобы задать сложные вопросы :-) – Aaron Digulla 27 May 2015 в 19:25
  • 3
    Спасибо, что посмотрели! .. Мы используем поплавки прямо сейчас, так как это было согласовано десять лет назад. Я старался увидеть вашу точку зрения на эту ситуацию на последующих этапах. благодаря! – Sendi_t 27 May 2015 в 19:33
  • 4
    @Sendi_t Непонимание. Я не могу ответить на ваш вопрос в 512 символов. Пожалуйста, задайте правильный вопрос и отправьте мне ссылку. – Aaron Digulla 28 May 2015 в 07:20
  • 5
    @GKFX Нет «одного размера подходит для всех». когда дело доходит до обработки десятичных знаков на компьютерах. Но так как большинство людей этого не понимает, я указываю их на BigDecimal, так как это уловит большинство распространенных ошибок. Если все слишком медленно, им нужно больше узнать и найти способы оптимизации своих проблем. Преждевременная оптимизация - корень всего зла - Д.Е. Кнут. – Aaron Digulla 18 August 2016 в 14:56

Сегодня я столкнулся с этой проблемой и не мог использовать рефакторинг для BigDecimal, потому что проект действительно огромный.

Обратите внимание, что вызов result.doubleValue () возвращает 5623.22998046875

Но вызов doubleResult.doubleValue () правильно возвращает 5623.23

Но я не совсем уверен, правильно ли это решение.

14
ответ дан Andrew 25 August 2018 в 04:38
поделиться
  • 1
    Работал для меня. Также очень быстро. Не уверен, почему это не помечено как ответ. – Sameer 10 May 2013 в 13:01
  • 2
    Это метод, который я использую, и вам не нужна новая часть Float ... Просто создайте FloatingDecimal с помощью примитива. Он будет автоматически вставлен в коробку ... И работает тоже быстро ... Существует один, один недостаток, FloatingDecimal неизменен, поэтому вам нужно создать один для каждого отдельного поплавка ... представьте вычислительный код O (1e10)! !! Конечно, BigDecimal имеет тот же недостаток ... – Mostafa Zeinali 25 August 2014 в 05:38
  • 3
    Недостатком этого решения является то, что sun.misc.FloatingDecimal является внутренним классом JVM, а подпись его конструктора была изменена в Java 1.8. Никто не должен использовать внутренние классы в реальной жизни. – Igor Bljahhin 29 December 2015 в 12:43

Это связано с контрактом Float.toString(float), , который частично говорит:

Сколько цифр должно быть напечатано для дробной части [& hellip;]? Должна быть хотя бы одна цифра для представления дробной части, а кроме нее столько, сколько всего, больше цифр, которые необходимы, чтобы однозначно различать значение аргумента от смежных значений типа float. That Предположим, что x - точное математическое значение, представленное десятичным представлением, созданным этим методом, для конечного ненулевого аргумента f. Тогда f должно быть значением float, ближайшим к x; или, если два значения float одинаково близки к x, то f должен быть одним из них, а младший значащий бит значения f должен быть 0.

23
ответ дан erickson 25 August 2018 в 04:38
поделиться
  • 1
    +1 Отличный ответ с цитатой из документации. – EMP 28 July 2010 в 03:09

Я нашел следующее решение:

public static Double getFloatAsDouble(Float fValue) {
    return Double.valueOf(fValue.toString());
}

Если вы используете float и double вместо Float и Двойной используйте следующее:

public static double getFloatAsDouble(float value) {
    return Double.valueOf(Float.valueOf(value).toString()).doubleValue();
}
4
ответ дан GSD.Aaz 25 August 2018 в 04:38
поделиться

Я считаю, что преобразование в двоичное представление проще для понимания этой проблемы.

float f = 0.27f;
double d2 = (double) f;
double d3 = 0.27d;

System.out.println(Integer.toBinaryString(Float.floatToRawIntBits(f)));
System.out.println(Long.toBinaryString(Double.doubleToRawLongBits(d2)));
System.out.println(Long.toBinaryString(Double.doubleToRawLongBits(d3)));

Вы можете видеть, что float расширяется до double, добавляя 0s к концу, но двойное представление 0.27 является «более точным», следовательно, проблема.

   111110100010100011110101110001
11111111010001010001111010111000100000000000000000000000000000
11111111010001010001111010111000010100011110101110000101001000
32
ответ дан Jimmy Kane 25 August 2018 в 04:38
поделиться

Для информации это относится к пункту 48 - Избегайте float и double, когда требуются точные значения, из Effective Java 2nd edition от Джошуа Блоха. Эта книга - варенье, наполненное хорошими вещами, и, безусловно, стоит посмотреть.

0
ответ дан mR_fr0g 25 August 2018 в 04:38
поделиться

Поплавки по своей природе неточны и всегда имеют аккуратные округлые «проблемы». Если точность важна, вы можете рассмотреть возможность рефакторинга приложения для использования Decimal или BigDecimal.

Да, поплавки вычисляются быстрее, чем десятичные числа из-за поддержки процессора. Однако вы хотите быстро или точно?

1
ответ дан NotMe 25 August 2018 в 04:38
поделиться
  • 1
    Десятичная арифметика тоже неточна. (например, 1/3 * 3 == 0.999999999999999999999999999999). Разумеется, лучше представлять точные десятичные количества, такие как деньги, но для физических измерений это не имеет никакого преимущества. – dan04 25 August 2010 в 15:39
  • 2
    Но 1 == 0.9999999999999999999999999999 :) – Emmanuel Bourg 4 July 2012 в 22:46

Это работает?

float flt = 145.664454;

Double dbl = 0.0;
dbl += flt;
0
ответ дан Zizouz212 25 August 2018 в 04:38
поделиться
Другие вопросы по тегам:

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