很多程序员都知道C中有几种浮点类型。到目前为止,我知道float
,double
和long double
,但我不确定它们是否都是,因为我发现了几个类似__DEC32_MAX__
的定义。起初我以为这是__FLT_MAX__
的另一个名称,但当我试图打印它时,我意识到它是不同的(如下所示):
#include <stdio.h>
void main(void)
{
__mingw_printf("flt value: %e, size: %d\n", __FLT_MAX__, sizeof(__FLT_MAX__));
__mingw_printf("dbl value: %e, size: %d\n", __DBL_MAX__, sizeof(__DBL_MAX__));
__mingw_printf("ldbl value: %e, size: %d\n", __LDBL_MAX__, sizeof(__LDBL_MAX__));
__mingw_printf("dec32 value: %e, size: %d\n", __DEC32_MAX__, sizeof(__DEC32_MAX__));
__mingw_printf("dec64 value: %e, size: %d\n", __DEC64_MAX__, sizeof(__DEC64_MAX__));
__mingw_printf("dec128 value: %e, size: %d\n", __DEC128_MAX__, sizeof(__DEC128_MAX__));
}
/* output:
flt value: 3.402823e+038, size: 4
dbl value: 1.797693e+308, size: 8
ldbl value: 3.237664e-317, size: 16
dec32 value: 9.944455e-315, size: 4
dec64 value: 9.089022e+269, size: 8
dec128 value: 3.237656e-317, size: 16
*/
什么是**DEC***?
还有其他我不知道的浮点类型吗?
3条答案
按热度按时间aemubtdh1#
在C23之前的C中只有3 real floating-point types:
float
、double
和long double
,它们可以使用十进制或八进制等任意基数作为有效位,尽管现在最有可能使用二进制。一些较老的系统使用hexadecimal floating-point types。每种真实的浮点类型都可以与_Complex
或_Imaginary
关键字组合,以生成复杂浮点类型添加了C233 more real floating-point types:
_Decimal32
、_Decimal64
和_Decimal128
,均为十进制类型如果您看到其他内容,则可能是 * 编译器扩展 * 或 * 内部编译器内容 *。这些内容将以
__
为前缀,因为以双下划线开头的标识符是为实现保留的。__mingw_printf
,__DBL_MAX__
,__DEC64_MAX__
...都是实现内部的,您不应该直接使用它们。请使用FLT_MAX
而不是__FLT_MAX__
事实上在C23之前GCC中有一个十进制浮点扩展
作为扩展,GNU C支持ISO/IEC WDTR 24732的N1312草案中定义的十进制浮点类型。GCC中对十进制浮点类型的支持将随着技术报告草案的变化而发展。任何目标的调用约定也可能改变。并非所有目标都支持十进制浮点类型。
十进制浮点类型是
_Decimal32
、_Decimal64
和_Decimal128
,它们使用的基数是10,而浮点类型float
、double
和long double
的基数不是由C标准指定的,而是通常为2。∮ ∮ ∮ ∮ ∮
由于mingw是GCC端口,它也支持十进制浮点扩展。通常在
float.h
中,标准常量将被定义为特定于实现的常量,例如7lrncoxx2#
十进制类型非常特殊,非常有趣,但还不是标准的。它们使用internal fraction representation which is based on base 10,而不是以2为基数。请特别参见IEEE 754 - 2008。
所有关于0.1 not being exactly representable和0.1 + 0.2 not exactly equaling 0.3的重要的、不幸的、令人厌烦的争论都消失了,计算机浮点几乎奇迹般地可以像我们都习惯了的十进制浮点一样工作!但是这些类型以及它们所需要的
printf
支持还不是标准的、流行的或众所周知的。在IEEE 754 - 2008中,两种主要的十进制类型是
decimal32
和decimal64
,它们是我们熟悉的二进制float
和double
的十进制对应物,还有类似于long double
的decimal128
。脚注:严格来说,说
decimal32
和其他类型是我们"熟悉的二进制"浮点类型(如float
和double
)的"十进制对应物"并不完全正确。新的十进制类型AFAIK确实保证是十进制的。但传统类型float
、double
、和long double
并不一定是二进制的,它们通常在你可能使用的每一台机器上都是二进制的,但它们也可能是十进制的,在少数几台本机实现浮点且只使用十进制的旧机器上。你会注意到FLT_RADIX
从<float.h>
到FLT_RADIX
是10lx0bsm1f3#
某些特定用途需要小浮子,例如:
float8
和float16
和bifloat
它主要用于DSP、AI和图形应用,许多硬件架构至少支持其中的一部分(例如双浮点AVX-512 BF 16、ARM-V8.8、AMD ROCm、CUDA等等)。也有像float 128这样的大浮点数格式。PowerPC中的VSX。
标准C语言并不直接支持这些浮点数。一些编译器将其作为扩展来支持。