浮点(或双精度)到十进制定点整数

时间:2014-12-10 14:29:50

标签: c floating-point

我想在C语言中将float或double转换为十进制定点整数。考虑到C语言的规范,我正在为这个问题寻找最合适(强大)的解决方案。

问题就是这样:

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

标准的相关元素(使用C99,ISO / IEC 9899:TC3,请参阅this question进行下载),据我所知:

  • 6.3.1.4 / 1:当实数浮动类型的有限值被转换为除_Bool以外的整数类型时,小数部分被丢弃(即,该值被截断为零)。 (...)
  • 6.4.4.2 / 3 :( ...)对于十进制浮点常数,(...)结果是最接近的可表示值,或者与最接近的可表示值紧邻的较大或较小的可表示值,在实现定义的方式。 (...)

示例中的15.6在IEEE double中没有精确的表示,所以除了d之外,我会得到略高于或低于某些值的东西。问题是"略低于"部分,然后示例中的i将无法获得例外结果(将获得155)。

我明显的看法是这样的(仅考虑零值或正值):

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

至少我是否正确地解释了C标准。我问,因为"实现定义"行为,可能会遇到一致的结果,而在现实中,其他一些实现可能会破坏程序,因此反复试验并不是找到合适解决方案的适当方法。

特别是the following question涉及到这个问题,我认为这个问题的答案是错误的。

1 个答案:

答案 0 :(得分:2)

C99为此目的指定了一个圆函数。使用它,然后转换为int。

更新:对于C89,您可以尝试

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

这应该与C99 round相同,除了小数部分等于0.5的负数将向上舍入(如Java),并且零可能被错误地签名(这是基于类似的技巧{ {3}})。