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

inf*_*ged 0 c++ floating-point

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

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

我认为其中一种方法是从数字中减去小数部分,但这并不是那么有效.那么,也许还有其他方法呢?

示例 -

float a = 123.456;

float b;

b = do something on a;
Run Code Online (Sandbox Code Playgroud)

结果b是123.0

Evg*_*Evg 7

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

float round(float arg);
double round(double arg);
Run Code Online (Sandbox Code Playgroud)

这也适用于std::floorstd::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

编译器:gcc 7.3.0msvs 2018 15.9.0,机器:Core i7-4770.

代码.编译选项:

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 ...

坦率地说,我不认为这些结果本身非常相关(绝对值).使用快速数学选项,某些功能仅减少到单个汇编指令vroundss.应该对实际代码进行分析以获得相关结果.


mel*_*ene 5

查看modf

#include <cmath>

float a = 123.456;
float b, c;

c = std::modf(a, &b);
// c = 0.456
// b = 123.0
Run Code Online (Sandbox Code Playgroud)

如果不需要,则不必使用返回值(小数部分)。

或者(C++11 起)trunc

float b = std::trunc(a);
Run Code Online (Sandbox Code Playgroud)