如何获取浮点数的小数部分?

4

我有一个x类型为float的变量,需要获取它的小数部分。我知道可以使用以下两种方法来获取其小数部分:

  • x - floorf(x)
  • fmodf(x, 1.0f)

我的问题是:其中一种方法总是比另一种更好吗?它们是否有效地相同?还有第三种替代方案吗?

注:

  • 如果答案取决于我正在使用的处理器,请让它是x86_64,并且如果您能详细说明其他处理器的行为,那就太好了。
  • 请确保并参考x的负值的行为。我不介意这个行为或者那个行为,但我需要知道这个行为是什么。

至少答案不应该依赖于处理器。 - Jabberwocky
我以前从未听说过 fmod(),所以我不得不试一试。当源数字为零或更小时,结果是不同的。这有关系吗? - Arthur Kalliokoski
2个回答

6
有没有第三种选择我可以考虑?
有专门的函数来做这件事。存在modff函数,可以将一个数分解为整数部分和小数部分。
``` float modff(float arg, float* iptr); ```
将给定的浮点数值`arg`分解为积分和分数部分,每个部分具有与`arg`相同的类型和符号。积分部分(以浮点格式)存储在由`iptr`指向的对象中。

2

我认为x - floorf(x)是相当好的(精确的),但在某些情况下不适用:

  • 对于负零或任何其他负整数浮点数,它具有错误的符号位(我们可能期望分数部分具有相同的符号位)。
  • 它在处理无穷大时效果不佳。

modff对于int和frac部分都尊重-0.0符号位,并且对于+/-inf分数部分回答+/-0.0-至少如果实现支持IEC 60559标准(IEEE 754)。
inf的原理可能是:由于每个大于2 ^ precision的浮点数都具有空分数部分,因此对于无限的浮点数也必须如此。

这只是小问题,但仍然不同。

编辑当应用于具有小数部分的负浮点数时,x - floor(x)最明显的缺陷是错误的。例如,对于-2.25,它将返回+0.75,这不是我们所期望的...

由于使用了c99标签,x - truncf(x)会更正确,但仍然会受到我最初关注的小问题的影响。


1
对于负数 xfloorf 将是比 x 小的最接近的整数。因此,例如 -3.2,我们将得到 -4.0,这将产生 -3.2 - (-4.0) = 0.8,这不仅是错误的符号。 - StoryTeller - Unslander Monica
@StoryTeller-UnslanderMonica 哎呀,谢谢你指出这个问题,我太专注于零分数部分的符号,以至于错过了最明显的问题! - aka.nice

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接