所以我是c的新手,我刚刚了解了数据类型,让我感到困惑的是,例如,一个双倍的值范围是从2.3E-308到1.7E + 308 数学上有100个数字∈[2.3E-308,1.7E + 308]。 写这个简单的程序
#include <stdio.h>
int main()
{
double c = 5416751717547457918597197587615765157415671579185765176547645735175197857989185791857948797847984848;
printf("%le",c);
return 0;
}
结果是7.531214e + 18,通过%l改变%le,结果是7531214226330737664.000000 这不等于c。 所以最重要的是问题。
答案 0 :(得分:3)
这个长号实际上是long long
类型的数字文字。但由于此类型不能包含如此长的数字,因此会以模(LLONG_MAX + 1)
为模截断并生成7531214226330737360
。
修改:
@JohnBollinger:...然后转换为double,导致丢失一些(二进制)精度数字。
@rici:Demo2 - 此处常量的类型为double
,因为添加了小数点
答案 1 :(得分:1)
看起来,如果我们可以存储多达10的数量到电源308,我们存储308个数字左右,但是,在浮点运算中,情况并非如此。浮点数不会存储为大数字字符串。
从广义上讲,浮点数存储为尾数 - 通常是0到1之间的数字 - 和指数 - 某些数字被提升到其他数字的幂。不同种类的浮点数(float,double,long double)各自具有分配给尾数和指数的不同位数。这些位数,特别是在尾数中,控制着数字的精确度。
大多数平台上的双精度数提供16-17的十进制数字精度,无论幅度(十次幂)。虽然这些功能不是内置在C中,但可以使用能够以任何精度要求算术的库。
另一个复杂因素是,在您的示例中,您分配给c
的数字实际上并未定义为浮点数。如果没有任何迹象表明它应该如此表示,编译器会将其视为一个整数,因为它太大而不适合大多数平台上的最大整数类型,它会被截断到整数范围。
答案 2 :(得分:1)
您应该获得正确的编译器或启用警告。最近的GCC,只有默认设置将输出以下警告:
% gcc float.c
float.c: In function ‘main’:
float.c:4:12: warning: integer constant is too large for its type
double c = 5416751717547457918597197587615765157415671579185765176547645735175197857989185791857948797847984848;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
请注意,它表示整数,即整数,而不是浮点数。在C中,该形式的常量表示整数。除非以U
为后缀,否则它还是 signed 整数,它是最适合的类型。但是,标准C和常见实现都没有足够大的类型来适应此值。那么会发生什么,是[(C11 6.4.4.1p6)[http://port70.net/~nsz/c/c11/n1570.html#6.4.4.1p6]):
如果整数常量不能由其列表中的任何类型表示,并且没有扩展的整数类型,那么整数常量没有类型。
在算术中使用没有类型的这种整数常量会导致未定义的行为,也就是整个程序的执行现在毫无意义。你应该阅读警告。
“修复”可能是在数字后添加.
!
#include <stdio.h>
int main(void)
{
double c = 54167517175474579185971975876157651574156715791\
85765176547645735175197857989185791857948797847984848.;
printf("%le\n",c);
}
运行它:
% ./a.out
5.416752e+99
请注意,即使这样,double
也只能精确平均~15个有效十进制数字。