C 如何确定浮点值是否为整数?

C 如何确定浮点值是否为整数?,c,C,我有一个程序,如果是浮点数,我需要打印浮点数;如果是正则数,我需要打印整数 例如伪代码 float num = 1.5; if (num mod sizeof(int)==0) printf ("INTEGER"); else printf("FLOAT"); 例如: float z = powf(powf(3.0f, 0.05f), 20.0f); if (roundf(z) == z) { printf("integer\n"); } else {

我有一个程序,如果是浮点数,我需要打印浮点数;如果是正则数,我需要打印整数

例如伪代码

float num = 1.5; 
if (num mod sizeof(int)==0)
  printf ("INTEGER");
else
  printf("FLOAT");
例如:

float z = powf(powf(3.0f, 0.05f), 20.0f);

if (roundf(z) == z) {
    printf("integer\n");
} else {
    printf("fraction\n");
}
1.6将打印浮动 1.0将打印整数 像这样的东西行吗

像这样的东西行吗

否。例如,在x86_32和ARM 32位体系结构上,sizeofint==4和sizeofloat==4


另外,无论您认为mod是什么,它清楚地表明您不了解sizeof运算符的作用。

所有浮点类型都具有相同的大小,因此您的方法无法工作。您可以使用ceilf检查浮点是否为整数

您可以使用modff:

modff将接受一个float参数,并将其分解为整数和小数部分。它将整数部分存储在第二个参数中,并返回小数部分。

这是一种简单的方法,但有一个陷阱: 您可以使用roundf,如下所示:

float z = 1.0f;

if (roundf(z) == z) {
    printf("integer\n");
} else {
    printf("fraction\n");
}
这项技术和其他类似技术(如ceilf)的问题在于,尽管它们对整数常量非常有效,但如果数字是受到浮点舍入误差影响的计算结果,它们将失败。例如:

float z = powf(powf(3.0f, 0.05f), 20.0f);

if (roundf(z) == z) {
    printf("integer\n");
} else {
    printf("fraction\n");
}
打印分数,即使31/2020应等于3,因为实际计算结果最终为2.999992847442626953125

那么我们该如何应对呢? 任何类似的方法,无论是fmodf还是其他方法,都受此约束。在执行复杂或易于舍入的计算的应用程序中,通常要做的是为构成整数的部分定义一些公差值,这通常适用于浮点等式比较。我们通常称之为容忍度ε。例如,假设计算机的舍入误差高达+/-0.00001,我们将予以原谅。然后,如果我们测试z,我们可以选择0.00001的ε,并执行以下操作:

if (fabsf(roundf(z) - z) <= 0.00001f) {
    printf("integer\n");
} else {
    printf("fraction\n");
}
您不想在这里使用ceilf,因为例如,ceilf1.0000001是2而不是1,ceilf-1.9999999是-1而不是-2


选择适合您的应用程序的公差值。有关更多信息,请参阅上的这篇文章。

您是想在宏或其他方面实现这一点吗?否则,类型总是已知的。使用sizeof肯定不起作用。你需要提供一个更大的例子来说明你是如何使用它的。否则,您真的不清楚为什么您不知道它是浮点还是int。请说明您打算如何在readl代码中使用它,而不是伪代码。因为它在使用静态变量类型的语言中没有真正意义。您是否在尝试区分变量类型?或者只是某些值?你的问题真的是我如何确定浮点值是否为整数?如果C11是一个选项,则可以使用_Generic。你要回答标题中的问题吗?@Barmar这是对问题早期版本的回答。现在问题更清楚了,这应该被编辑或删除。即使是原始版本也会问我如何才能。。。在标题中,它不仅仅询问伪代码是否有效。@Barmar:无论这是否完全回答了问题,这都是关于为什么原始尝试不可行的有用信息。谢谢!这是一个很好的技巧。@Vandervidi这不是一个真正可靠的检查整数或比较浮点数的方法,除非是在非常简单和可预测的情况下。请看,我在中有详细信息。@JasonC:这个答案完全符合问题的要求;它确定浮点值是否表示整数。所以它是完全可靠的。@OliCharlesworth它实际上不可靠。powfpowf3.0f、0.05f、20.0f是否不表示整数?从数学上讲,3^1/20^20是一个整数,其目的是执行该计算-一个表示整数的结果是可以预期的。然而,这个答案声称它不是一个整数。众所周知,盲==对于比较浮点值来说并不可靠,舍入误差是需要处理的问题。浮点值比整数要小心得多。这个问题也存在于更多的人身上,而不仅仅是OP.@JasonC:IMHO,浮点计算不能给出理想的数学结果是另一个问题。要确定num是否表示一个精确的整数值,无疑有充分的理由。如果num的计算结果存在舍入错误,导致数值与整数稍有不同,则此操作将失败。@Jason C IMO:与整数稍有不同的数字不是整数。为这种检测函数提供的参数应该被认为是精确的。这是math.h函数的质量评估-提供的答案基于输入准确的假设。你可以做一个2参数函数Foo2x,RangeEnFig,按照你的建议做更多的事情。@ Jasnc:如果你想思考一个更奇怪的例子,那么考虑一下。@杰森C PoSfopopWfPuf3,1/3,
20; -> 整数\n。当然,您的编译将返回相同的结果。putsfopowfpowf3,1.0/20,20;可能会打印FLOAT\n因为典型的double实际上做的事情更接近powfpowf3,0.0500000000000000278,20,并且不应产生整数。pow调用混淆了二进制FP的1.0/20不精确性,这是问题的核心。@Jason C确定double的整数不精确性的调用只是对modf、ceil等的调用。确定double的近整数不精确性的测试要复杂得多,需要一个额外的参数来衡量其接近性。相对、绝对或其他接近度的定义并不琐碎,对于一般用途的解决方案来说很少令人满意,而且,依我看,肯定远远超出OP的要求。关于FP数学的精确性,你的观点很重要,但在这篇文章的末尾,这实际上取决于应用程序。如果他关心的只是浮点没有小数部分,那么使用epsilon技巧将产生错误的答案,即1.0000001应该是float@jh314是的,epsilon应始终根据应用程序选择,0可能对某些应用程序有效。然而,将这些信息放在答案中是很重要的。虽然OP可能不在乎,但这个问题肯定会出现在检查float是否为整数的搜索结果顶部,完整性有助于减少错误/误报。
if (fabsf(roundf(z) - z) <= 0.00001f) {
    printf("integer\n");
} else {
    printf("fraction\n");
}