C语言中有多少种浮点类型?

h7appiyu  于 2023-03-07  发布在  其他
关注(0)|答案(3)|浏览(228)

很多程序员都知道C中有几种浮点类型。到目前为止,我知道floatdoublelong 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***?
还有其他我不知道的浮点类型吗?

aemubtdh

aemubtdh1#

在C23之前的C中只有3 real floating-point typesfloatdoublelong 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,而浮点类型floatdoublelong double的基数不是由C标准指定的,而是通常为2。
∮ ∮ ∮ ∮ ∮
由于mingw是GCC端口,它也支持十进制浮点扩展。通常在float.h中,标准常量将被定义为特定于实现的常量,例如

#define LDBL_MAX   __LDBL_MAX__
#define DEC128_MAX __DEC128_MAX__
7lrncoxx

7lrncoxx2#

十进制类型非常特殊,非常有趣,但还不是标准的。它们使用internal fraction representation which is based on base 10,而不是以2为基数。请特别参见IEEE 754 - 2008。
所有关于0.1 not being exactly representable0.1 + 0.2 not exactly equaling 0.3的重要的、不幸的、令人厌烦的争论都消失了,计算机浮点几乎奇迹般地可以像我们都习惯了的十进制浮点一样工作!但是这些类型以及它们所需要的printf支持还不是标准的、流行的或众所周知的。
在IEEE 754 - 2008中,两种主要的十进制类型是decimal32decimal64,它们是我们熟悉的二进制floatdouble的十进制对应物,还有类似于long doubledecimal128
脚注:严格来说,说decimal32和其他类型是我们"熟悉的二进制"浮点类型(如floatdouble)的"十进制对应物"并不完全正确。新的十进制类型AFAIK确实保证是十进制的。但传统类型floatdouble、和long double并不一定是二进制的,它们通常在你可能使用的每一台机器上都是二进制的,但它们也可能是十进制的,在少数几台本机实现浮点且只使用十进制的旧机器上。你会注意到FLT_RADIX<float.h>FLT_RADIX是10

lx0bsm1f

lx0bsm1f3#

某些特定用途需要小浮子,例如:float8float16bifloat它主要用于DSP、AI和图形应用,许多硬件架构至少支持其中的一部分(例如双浮点AVX-512 BF 16、ARM-V8.8、AMD ROCm、CUDA等等)。
也有像float 128这样的大浮点数格式。PowerPC中的VSX。
标准C语言并不直接支持这些浮点数。一些编译器将其作为扩展来支持。

相关问题