C++ 从float中删除小数部分但保留类型的有效方法

C++ 从float中删除小数部分但保留类型的有效方法,c++,floating-point,C++,Floating Point,我知道通过std::round、std::floor或std::ceil或简单的类型转换,我们可以删除小数部分,但是通过类型转换,变量会丢失其原始类型(float或double) 有没有办法,我可以保留类型,但仍然有效地删除小数部分 我认为其中一种方法是从数字中减去小数部分,但效率不高。那么,也许还有其他方法 范例- float a = 123.456; float b; b = do something on a; 结果b为123.0例如,使用std::round保留原始类型: floa

我知道通过std::round、std::floor或std::ceil或简单的类型转换,我们可以删除小数部分,但是通过类型转换,变量会丢失其原始类型(float或double)

有没有办法,我可以保留类型,但仍然有效地删除小数部分

我认为其中一种方法是从数字中减去小数部分,但效率不高。那么,也许还有其他方法

范例-

float a = 123.456;

float b;

b = do something on a;

结果b为123.0

例如,使用
std::round
保留原始类型:

float round(float arg);
double round(double arg);
这同样适用于
std::floor
std::ceil

添加。以下是一些基准测试结果

Compiler raw loop std::ceil std:floor std::trunc std::round -------------------------------------------------------------------- gcc 8.36 8.20 8.19 8.21 32.95 gcc(f) 2.88 8.20 8.20 8.20 11.01 msvs 8.20 28.47 31.90 67.14 97.84 msvs(f) 8.13 13.70 14.00 67.27 97.50 坦率地说,我不认为这些结果本身就非常相关(绝对值)。使用“快速数学”选项,某些函数仅简化为一条汇编指令。应分析真实代码以获得相关结果。

请检查:


为什么你不能先转换成int,然后再转换成float,让编译器来处理呢?@MeetTitan这真是麻烦。
float
的范围远大于
int
@MeetTitan
[conv.fpint]
“浮点型prvalue可以转换为整型prvalue。转换截断;也就是说,小数部分被丢弃。如果目标类型中无法表示截断的值,则行为未定义。“
b=(int)a、 
应该可以。@melpomene,不是在粒度上。如果你取一个32位浮点,并尝试将其赋值为一个32位的整数左值,你可能会感到惊讶……这远远低于32位整数类型的范围。在我的例子中,由于缺少有效位,我得到了
1000000128
s在浮点中,在整数对应项中使用。:)哦..那很简单..我不知道round/floor/ceil保留了该类型。但有意义。这实际上是比公认的答案“更大”的答案,我想。@RudyVelthuis为什么?它没有回答标题中的问题(如何删除数字的小数部分)@RudyVelthuis-好吧,问题是要有效地删除分数部分,因为它将被使用的数据集是巨大的。我没有进行基准测试,但我强烈认为trunc将在其他参赛者中获胜。我已经将主题行更改为更具体。@Infoblock在回答问题后请不要更改您的问题;如果您你有一个新问题,把它当作一个新问题来问。答案很好。trunc和modf与round有什么区别(我现在知道,那一轮保留了这个类型)?@infoblock
round
将整数舍入最接近的整数(远离0),例如
round(0.7)
1.0
,但是
trunc(0.7)
0.0
(它只是去掉了小数部分)。看起来trunc真的很笨,应该是所有方面中最快的,ceil,floor等等。这对我来说很有用。@InfoBulled:trunc()不是“笨”。将FP值转换为整数值需要一些工作,这与floor()或ceil()甚至round()的工作是一样的@melpemone:哪些位/多少位?但你没有将某些位设置为0。你必须知道可以删除多少位,然后必须舍入到最后一个剩余位的位置,然后对结果进行规范化。这比只删除一些位要多一些工作。但通常在硬件中是这样,所以没什么大不了的。 gcc: --std=c++17 -O3 -m64 -march=native -fno-tree-vectorize gcc(f): --std=c++17 -O3 -m64 -march=native -ffast-math -fno-tree-vectorize msvs: /fp:precise /fp:except /O2 /std:c++latest ... msvs(f): /fp:fast /fp:except- /O2 /std:c++latest ...
#include <cmath>

float a = 123.456;
float b, c;

c = std::modf(a, &b);
// c = 0.456
// b = 123.0
float b = std::trunc(a);