Приклад:
float timeRemaining = 0.58f;
Чому f
в кінці цього числа потрібно ввести?
Приклад:
float timeRemaining = 0.58f;
Чому f
в кінці цього числа потрібно ввести?
double & int
.
Відповіді:
Ваша декларація про поплавок містить дві частини:
timeRemaining
має тип float
.0.58
цій змінній.Проблема виникає в частині 2.
Права сторона оцінюється самостійно. Відповідно до специфікації C # число, що містить десяткову крапку, що не має суфікса, інтерпретується як a double
.
Отже, тепер у нас є double
значення, яке ми хочемо призначити змінній типу float
. Для цього потрібно мати неявне перетворення з double
на float
. Такого перетворення не існує, оскільки ви можете (і в даному випадку це) втратити інформацію під час перетворення.
Причина полягає в тому, що значення, яке використовує компілятор, насправді не 0,58, а значення з плаваючою комою, найближче до 0,58, що становить 0,579999999999978655962351581366 ... для double
і рівно 0,579999946057796478271484375 для float
.
Строго кажучи, цього f
не потрібно. Ви можете уникнути необхідності використовувати f
суфікс, додавши значення float
:
float timeRemaining = (float)0.58;
(float) 0.58
працювати? Ви вже говорили раніше, що конверсії немає, оскільки інформація може бути втрачена, то як же тоді буде працювати акторський склад?
2.4
усюди трактується як подвійний. 2. Неявні перетворення звуження (наприклад, з подвійного на плаваючий) не дозволяються. Якщо ви хочете зробити виняток із цих правил, то у вас повинна бути дуже поважна причина. Збереження 1 натискання клавіші навряд чи буде достатньо хорошим.
Оскільки існує кілька числових типів , які компілятор може використовувати для подання значення 0.58
: float
, double
і decimal
. Якщо ви не в порядку з компілятором, який вибирає для вас, вам доведеться неоднозначно визначити.
У документації для double
зазначено, що якщо ви не вказуєте тип самі, компілятор завжди вибирає double
як тип будь-якого реального числового літералу:
За замовчуванням дійсний числовий літерал праворуч від оператора присвоєння розглядається як подвійний. Однак, якщо ви хочете, щоб ціле число розглядалося як подвійне, використовуйте суфікс d або D.
Додавання суфікса f
створює a float
; суфікс d
створює a double
; суфікс m
створює a decimal
. Усі вони також працюють з великої літери.
Однак цього все ще недостатньо, щоб пояснити, чому це не компілюється:
float timeRemaining = 0.58;
Недостатня половина відповіді полягає в тому, що перетворення з double
0.58
до float
timeRemaining
потенційно втрачає інформацію, так що компілятор відмовляється застосовувати його в неявному вигляді . Якщо ви додасте явний привід, перетворення виконується; якщо ви додасте f
суфікс, перетворення не буде потрібно. В обох випадках код потім компілюється.
int
і одне для double
.
double a = 0.69f;
?
float
в double
.
Проблема полягає в тому, що .NET, щоб дозволити виконувати деякі типи неявних операцій із залученням, float
і double
потрібно було явно вказати, що має відбуватися у всіх сценаріях, що включають змішані операнди, або дозволити неявні перетворення між типами виконувати в одному лише напрямок; Microsoft вирішила слідувати лідерству Java, дозволяючи напрям, який час від часу сприяє точності, але часто жертвує коректністю і, як правило, створює клопоти.
Майже у всіх випадках, якщо double
значення, яке є найближчим до певної числової величини, і присвоєння йому значення a, float
вийде float
значення, яке є найближчим до тієї самої величини. Є кілька кутових випадків, наприклад, вартість 9 007 199 991 611 905; найкраще float
представлення буде 9 007 200 328 482 816 (що на 536 870 911), але найкраще double
представлення (тобто 9 007 199 991 611 904) float
дає 9 007 199 254 740 992 (що на 536 870 913). Загалом, хоча перетворення найкращого double
подання деякої величини у float
або дасть найкраще можливе float
подання, або одне з двох подань, які по суті однаково хороші.
Зверніть увагу, що така бажана поведінка застосовується навіть у крайніх випадках; наприклад, найкраще float
подання для величини 10 ^ 308 відповідає float
поданню, досягнутому перетворенням найкращого double
подання цієї величини. Подібним чином найкраще float
подання 10 ^ 309 відповідає float
поданню, досягнутому перетворенням найкращого double
подання цієї величини.
На жаль, перетворення в напрямку, який не вимагає явного приведення, рідко бувають десь настільки точними. Перетворення найкращого float
подання значення в double
рідко дає щось особливо наближене до найкращого double
подання цього значення, а в деяких випадках результат може бути вимкнено на сотні порядків (наприклад, перетворення найкращого float
подання 10 ^ 40 в double
отримає значення, яке порівнює більше, ніж найкраще double
подання 10 ^ 300.
На жаль, правила перетворення є такими, якими вони є, тому доводиться жити з використанням безглуздих наборів шрифтів та суфіксів при перетворенні значень у "безпечному" напрямку, і бути обережним при неявних наборах шрифтів у небезпечному напрямку, що часто дасть помилкові результати.
double
.