将浮点数结果保存到第三位,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);
更新:
问题已更新,要求非常矛盾。如果你有一个 exact 0.003
数字,它后面会有 infinite 个零,它是一个数学 属性 的数字。 OTOH,float
表示不能保证精确表示 3 个十进制数字的每个确切数字。要解决此问题,您需要放弃使用 float
类型并切换到某种定点表示形式。
0.00367 -> 0.003
一个float
通常可以精确表示大约232个不同的值。 0.00367
和 0.003
不在那个集合中。
最接近 float
到 0.00367
的是 0.0036700000055134296417236328125
最接近 float
到 0.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';
如何将结果四舍五入到第三位后的第三位。
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);
更新:
问题已更新,要求非常矛盾。如果你有一个 exact 0.003
数字,它后面会有 infinite 个零,它是一个数学 属性 的数字。 OTOH,float
表示不能保证精确表示 3 个十进制数字的每个确切数字。要解决此问题,您需要放弃使用 float
类型并切换到某种定点表示形式。
0.00367 -> 0.003
一个float
通常可以精确表示大约232个不同的值。 0.00367
和 0.003
不在那个集合中。
最接近 float
到 0.00367
的是 0.0036700000055134296417236328125
最接近 float
到 0.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';