C-打印浮点值-在转换为int时精度下降
C - Printing a float - loss of precision when casting to int
我正在尝试制作一个函数,使我能够打印浮点值。现在,我遇到了两种奇怪的行为:有时,像1.3这样的值显示为1.2999999而不是1.300000,有时像1.234567这样的值则显示为1.2345672而不是1.2345670。
这是源代码:
int ft_putflt(float f)
{
int ret;
int intpart;
int i;
ret = 0;
i = 0;
intpart = (int)f;
ft_putnbr(intpart);
ret = ft_nbrlen(intpart) + 8;
write(1, ".", 1);
while (i++ < 7)
{
f *= 10;
ft_putchar(48 + ((int)f % 10));
}
return (ret);
}
ft_putnbr是OK AFAIK。ft_putchar是对"write(1,&c,1)"的简单调用。
test values (value : output)
1.234567 : 1.2345672 (!)
1.2345670 : 1.2345672 (!)
1.0000001 : 1.0000001 OK
0.1234567 : 0.1234567 OK
0.67 : 0.6700000 OK
1.3 : 1.3000000 OK (fixed it)
1.321012 : 1.3210119 (!)
1.3210121 : 1.3210122 (!)
这一切对我来说似乎有点神秘……在向int投射时可能会失去精度?
是的,在处理浮点和int时会丢失精度。
如果两个浮点数的大小不同,并且都使用完整的精度范围(约为7位小数),那么是的,您将在最后几位看到一些损失,因为浮点数以(符号)(尾数)×2(指数)的形式存储。如果两个值有不同的指数,并且将它们相加,那么较小的值将减少到尾数中的较少数字(因为它必须适应较大的指数):
PS> [float]([float]0.0000001 + [float]1)
1
关于整数,一个正常的32位整数能够精确地表示不完全适合浮点的值。float仍然可以存储大约相同的数字,但不再精确。当然,这只适用于足够大的数字,例如超过24位的数字。因为浮点有24位精度,(32位)整数有32位,所以浮点仍然能够保留幅度和大多数有效数字,但最后几位可能不同:
PS> [float]2100000050 + [float]100
2100000100
这是使用有限精度数值表示方案所固有的。给定任何可以表示的数字,A,有一个数字是可以表示的大于A的最小数字,称之为B。A和B之间的数字不能精确表示,必须近似。
例如,让我们考虑使用六位十进制数字,因为这是一个更容易理解的系统作为起点。如果A是.333333,那么B是.33334。介于A和B之间的数字,例如1/3,无法精确表示。因此,如果你取1/3并将其与自身相加两次(或乘以3),你会得到.999999,而不是1。你应该预料到这种表述的局限性是不精确的。
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 为什么将双精度转换为 int 似乎在第 16 位数字之后将其四舍五入?
- 主.cpp:18:20:错误:从"int*"转换为"int"会失去精度 [-fa
- 如何解决隐式转换丢失整数精度:'size_t'(又名"无符号长")到'int'警告?
- int 到浮点转换的精度损失
- 将非常大的 int 转换为双倍,在某些计算机上会损失精度
- f 是指向函数的指针,该函数采用 int,并返回指向不带任何内容并返回双精度的函数的指针
- 将双精度值分配给 int 数组时的类型转换
- 标准::p空气<矢量、双精度的初始值设定项列表<int>>
- 如果我在 C++ 中为 int 提供双精度,输入缓冲区中存储了什么?
- 是否应该避免这种从 int 到双精度的静态转换?
- 在 C++ 中将 int 转换为双精度
- 将大双精度转换为无符号 int 期间堆栈损坏
- 将 int 转换为双精度以执行 std::complex <double>的"*"操作
- C++错误:从“int*”转换为“int”会失去精度
- 从 double* 转换为 int 会失去精度
- 隐式转换会丢失整数精度:'long' 到 'int'
- C++ 将 int 转换为双精度不起作用
- 在算术表达式中,双精度会隐式转换为无符号 int 吗?
- C++:使用一对(cpp_int,int)整数作为无序映射中的键(其中cpp_int是boost多精度整数)