Приклад:
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.