简体   繁体   中英

Float (or double) to decimal fixed point integer

I would like to convert a float or double to a decimal fixed point integer in C language. I am searching the most appropriate (robust) solution for this problem, considering C language's specification.

The problem for example is along the lines of this:

double d = 15.6;
int    i;
...
i = (int)(d * 10.0); /* I am excepting getting 156 in 'i' */

Relevant elements of the standard (using a C99 one, ISO/IEC 9899:TC3, see this question for download) as far as I see:

  • 6.3.1.4 / 1: When a finite value of real floating type is converted to an integer type other than _Bool , the fractional part is discarded (ie, the value is truncated towards zero). (...)
  • 6.4.4.2 / 3: (...) For decimal floating constants, (...) the result is either the nearest representable value, or the larger or smaller representable value immediately adjacent to the nearest representable value, chosen in an implementation-defined manner. (...)

The 15.6 in the example has not got an exact representation in IEEE double, so I would except d to get something slightly above, or slightly below. The problem is with the "slightly below" part, then i in the example wouldn't get the excepted result (would get 155 instead).

My obvious take would be something like this (considering zero or positive values only):

i = (int)(d * 10.0 + 0.5);

At least if I interpreted the C standard correctly. I ask because due to the "implementation-defined" behavior, one may experience a consistent result while in the reality some other implementation may break the program, so trial and error is not an adequate method for finding an appropriate solution.

In particular the following question relates this problem, which I believe has an incorrect accepted answer.

C99 specifies a round function for exactly this purpose. Use that, then cast to int.

UPDATE: for C89, you could try

double y = floor(x);
double z = x == y ? x : floor(2.0*x-y);

This should give the same as C99 round , except that negative numbers with fractional parts equal to 0.5 will be rounded upwards (like Java), and zeros may be signed incorrectly (this is based on a similar trick due to Arch Robinson ).

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