Мені цікаво, в чому різниця між цими двома змінними в C:
float price = 3.00;
і
float price = 3.00f;
Яке використання суфікса f
в цьому випадку?
Мені цікаво, в чому різниця між цими двома змінними в C:
float price = 3.00;
і
float price = 3.00f;
Яке використання суфікса f
в цьому випадку?
Відповіді:
3.00
інтерпретується як a double
, на відміну від 3.00f
якого розглядається компілятором як a float
.
f
Суфікс просто повідомляє компілятор , який є float
і який є double
.
Див. MSDN (C ++)
float price = 7.50 / 2.50;
проти, float price = 7.50f / 2.50f;
тоді результат може відрізнятися через різну роздільну здатність. У першому випадку компілятору доведеться провести обчислення, а double
потім перетворити результат на float
. У другому випадку розрахунок проводиться в float
. Зверніть увагу, що якщо є лише одне значення, double
то все це обчислюється як double
. Компілятору C не дозволяється оптимізувати це, оскільки їх округлення буде відрізнятися. Так floatvarA = floatvarB / 2.0
працює гірше, ніж з 2.0f
.
На додаток до вже сказаного, відстеження 1,0 проти 1,0f є важливішим, ніж усвідомлюють багато людей. Якщо ви пишете такий код:
float x;
...
float y = x * 2.0;
Тоді х буде підвищено до дубля, оскільки 2.0 - це дубль. Компілятору заборонено оптимізувати просування, інакше це порушить стандарт C. Обчислення відбувається з подвійною точністю, а потім результат неявно усікається у поплавок. Це означає, що обчислення буде повільнішим (хоча і точнішим), ніж це було б, якби ви написали 2.0f або 2.
Якби ви написали 2, константа мала би тип int, який був би підвищений до плаваючого, а обчислення було б зроблено з "точністю плаваючої". Хороший компілятор попереджав би вас про цю акцію.
Детальніше про правила "звичайного арифметичного перетворення" читайте тут:
http://msdn.microsoft.com/en-us/library/3t4w2bkb%28v=vs.80%29.aspx
float y = x * 2.0;
. Насправді компілятор, вартий його солі, генерує одноточне множення для float y = x * (double)0.1f;
набагато вражаючого подвигу (але все ж правильної оптимізації).
double
множення, використовуючи, 2.0
а не 2.0f
. Компіляторам заборонено використовувати оптимізацію, яка змінила б числовий результат.
(float)((double)float_x * (double)float_y) == float_x * float_y
рівність, яку компілятор застосовує навпаки для цієї оптимізації. Це працює, оскільки наближення 2 як double
і float
однакові.
Оскільки несуфіксовані літерали з плаваючою крапкою є подвійними, а округлення означає, що навіть малі літерали можуть приймати різні значення при округленні до плаваючої та подвійної. Це можна спостерігати на наступному прикладі:
float f=0.67;
if(f == 0.67)
printf("yes");
else
printf("no");
Це виведе no
, оскільки 0.67
має інше значення при округленні до плаваючого, ніж при округленні до подвійного. З іншої сторони:
float f=0.67;
if(f == 0.67f)
printf("yes");
else
printf("no");
виходи yes
.
Суфікс можна вказати, використовуючи великі або малі літери.
Спробуйте також це:
printf(" %u %u\n", sizeof(.67f), sizeof(.67));
Перевірте @ codepade
Додавши ще кілька комбінацій порівнянь між плаваючими та подвійними типами даних.
int main()
{
// Double type constant(3.14) converts to Float type by
// truncating it's bits representation
float a = 3.14;
// Problem: float type 'a' promotes to double type and the value
// of 'a' depends on how many bits added to represent it.
if(a == 3.14)
std::cout<<"a: Equal"<<std::endl;
else
std::cout<<"a: Not Equal"<<std::endl;
float b = 3.14f; // No type conversion
if(b == 3.14) // Problem: Float to Double conversion
std::cout<<"b: Equal"<<std::endl;
else
std::cout<<"b: Not Equal"<<std::endl;
float c = 3.14; // Double to Float conversion (OK even though is not a good practice )
if(c == 3.14f) // No type conversion
std::cout<<"c: Equal"<<std::endl; // OK
else
std::cout<<"c: Not Equal"<<std::endl;
float d = 3.14f;
if(d == 3.14f)
std::cout<<"d: Equal"<<std::endl; // OK
else
std::cout<<"d: Not Equal"<<std::endl;
return 0;
}
Вихід:
a: Not Equal
b: Not Equal
c: Equal
d: Equal
Часто різниця не важлива, оскільки компілятор у будь-якому випадку перетворить подвійну константу в плаваючу. Однак враховуйте це:
template<class T> T min(T a, T b)
{
return (a < b) ? a : b;
}
float x = min(3.0f, 2.0f); // will compile
x = min(3.0f, 2); // compiler cannot deduce T type
x = min(3.0f, 2.0); // compiler cannot deduce T type