将浮点数结果保存到第三位,C 中不四舍五入

Save float result number to third digit, no rounding in C

如何将结果四舍五入到第三位后的第三位。

float result = cos(number);

请注意,我要将结果保存到第三位,不四舍五入。不,我不想用 .3f 打印它,我需要将它保存为新值;

示例:

 0.00367 -> 0.003

N.B。 3 之后不需要额外的零。

此外,我需要能够获得第 3 位数字。例如,如果它是 0.0037212,我想得到 3 并在某些计算中将其用作 int。

您可以放大该值,使用 trunc 向零截断,然后缩小:

float result = trunc(cos(number) * 1000) / 1000;

请注意,由于浮点数的不精确性,结果不会是精确值。

如果您要专门提取小数点后第三位,可以按如下方式进行:

int digit = (int)(result * 1000) % 10;

这将按比例放大数字,使相关数字位于小数点左侧,然后提取该数字。

您可以从除以 0.001 的余数中减去:

result -= fmod(result, 0.001);

Demo

更新:

问题已更新,要求非常矛盾。如果你有一个 exact 0.003 数字,它后面会有 infinite 个零,它是一个数学 属性 的数字。 OTOH,float 表示不能保证精确表示 3 个十进制数字的每个确切数字。要解决此问题,您需要放弃使用 float 类型并切换到某种定点表示形式。

0.00367 -> 0.003

一个float通常可以精确表示大约232个不同的值。 0.003670.003 不在那个集合中。

最接近 float0.00367 的是 0.0036700000055134296417236328125
最接近 float0.003__ 的是 0.0030000000260770320892333984375

I want to save the result up to the third digit

这个目标需要妥协。将结果保存到接近 0.001 倍数的 float

按 1000.0 缩放、截断并除以 1000.0 将适用于 大多数 值。

float y1 = truncf(x * 1000.0f) / 1000.0f;

上面给出了一个稍微错误的答案,其中一些值接近 x.xxx000...x.xxx999...。使用更高的精度可以解决这个问题。

float y2 = (float) (trunc(x * 1000.0) / 1000.0);

I want to get the 3 and use it as an int in some calculation.

跳过un-scaling部分,只保留1位fmod()

int digit = (int) fmod((trunc(x * 1000.0), 10);
digit = abs(digit);

最后,我怀疑这种方法不会完全满足 OP 未说明的 "use it as an int in some calculation."。 FP 数学有很多副标题,尤其是在尝试使用 binary FP 时,大多数 double 都是,在某种 decimal[=54= 中] 方式。

也许以下将满足 OP 的目标,即使它进行了 一些 舍入。:

int third_digit = (int) lround(cos(number)*1000.0) % 10;
third_digit = abs(third_digit);

矫枉过正,使用 sprintf()

double /* or float */ val = 0.00385475337;
if (val < 0) exit(EXIT_FAILURE);
if (val >= 1) exit(EXIT_FAILURE);
char tmp[55];
sprintf(tmp, "%.50f", val);
int third_digit = tmp[4] - '0';