简体   繁体   中英

C Language: Initializing float variable with a calculation

I haven't done a lot of floating point math programming in any language let alone in C.

I'm writing a temperature conversion program as an exercise and have a question about floating point numbers. I have a code frag as listed below. In both cases Temp1 and Temp2 are 0.0 when P_FahrenheitTemp is <> 32.0. However, if I use the CF3 factor in the calculation the LOC VERRKKKS!!! :-)

This seems intuitively obvious to me but... Is this compiler dependent or is a cast operator necessary on the initialization? BTW, I'm writing this code on an IBM iSeries platform using the C/C++ compiler which strictly adheres to ASNI and ISO standards.

Thank you in advance for any info!

Martin Kuester

#define CF3 5/9;

float Conv2Celsius(float P_FahrenheitTemp)
{
  float Temp1, Temp2, Temp3;
  float ConvAdj = 32.0;
  float CF1 = 0.555556;
  float CF2 = 5/9;

  //[°C] = ([°F] - 32) × 5/9
  Temp1 = (P_FahrenheitTemp - ConvAdj) * CF1; 
  Temp2 = (P_FahrenheitTemp - ConvAdj) * CF2;
  Temp3 = (P_FahrenheitTemp - ConvAdj) * CF3;

  return(Temperature);
}                                

Let us look closer.

  float CF1 = 0.555556;
  Temp1 = (P_FahrenheitTemp - ConvAdj) * CF1; 
  // same as 
  Temp1 = (P_FahrenheitTemp - ConvAdj) * (float) 0.555556;

  float CF2 = 5/9;
  Temp2 = (P_FahrenheitTemp - ConvAdj) * CF2;
  // same as 
  float CF2 = 0;  // 5/9 is integer division
  Temp2 = (P_FahrenheitTemp - ConvAdj) * 0;

  #define CF3 5/9
  Temp3 = (P_FahrenheitTemp - ConvAdj) * CF3;
  // same as 
  Temp3 = (P_FahrenheitTemp - ConvAdj) * 5 / 9;
  Temp3 = (P_FahrenheitTemp - ConvAdj) * 5.0f / 9;
  //      ^--- float  multiplication -------^             
  // same as 
  Temp3 = (P_FahrenheitTemp - ConvAdj) * 5.0f / 9.0f;
  //      ^--- float divsion ----------------------^             

Temp3 "VERRKKKS" because it is not scaling by 5/9 . Instead it is a text substitution in the line-of-code and so multiplies by 5 and then divides by 9.

Temp3 is correct and best of the three.
Temp1 is almost correct as not as certainly precise * (float) 0.555556 as * 5.0f/9.0f .
Temp2 is wrong as the answer is always 0, even when it should not be


I have a code frag as listed below. In both cases Temp1 and Temp2 are 0.0 when P_FahrenheitTemp is <> 32.0.

Temp1 is not 0.0.


To set aside the minor additional error in the constant, use at least 9 digits with float and a f suffix .

//float CF1 = 0.555556;
float CF1 = 0.555555556f;

Suggested replacement

float Conv2Celsius(float P_FahrenheitTemp) {
  float ConvAdj = 32.0f;
  float CF = 0.555555556f;

  //[°C] = ([°F] - 32) × 5/9
  return (P_FahrenheitTemp - ConvAdj) * CF; 
}              

In C language the line float CF2 = 5/9; will be processed as follows:

  1. The right side of the assignment operator 5/9 is evaluated first. The compiler here sees two integer values divided on each other so it will save the result into an integer temporary variable. This will lead to truncation of the fractional part of the actual result 0.555556 to 0 .
  2. The result will be assigned then to CF2.

What to do?

Alot of options; float CF2 = 5.0/9; or float CF2 = (float)5/9; or even float CF2 = 5./9;

the same with CF3

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM