C/C++ 数据类型 表示最大 最小数值 探讨

Posted _xiao_hu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C/C++ 数据类型 表示最大 最小数值 探讨相关的知识,希望对你有一定的参考价值。

 

C/C++中存储数字格式有整型和浮点型 字符型数据本质上也是以整型存储

 


整型

对于整型数据,最大值最小值很好计算

先确定对应数据型在本地所占用的字节数,同一数据型由于系统或者编译器的不同,所占字节不同,可以通过sizeof()函数查看,例如:

cout << sizeof(int) <<endl;

例如在我的电脑中 int 占用四个字节(即32位),1位符号位+31位数值位
所以int可表示的值得范围为 -2^31 — 2^31-1 (这里正负数不对称,减一是因为还有一个0)

同样的,对于整型都可以这么计算,通过所占字节数(即多少位)可以计算出它可以表示的最大最小值,需要注意的是对于无符号型,所有的位都是数值位,没有符号位,即没有负数。

 


浮点型

首先我们要知道,对于浮点型数据,计算机是以指数形式存储的。
即 a^b  a的b次方

具体格式
float型(通常为32位) 1位符号位+8位指数位+23位数值位(尾数位)

double型(通常为64位) 1位符号位+11位指数位+53位数值位(尾数位)

(这里数据型所占字节数可能也有差异,具体占用内存大小可通过之前的代码自行查看,这里选择一般情况作为举例)

顾名思义,符号位即0为正,1为负, 指数位表示次方大小,尾数位表示精度(precision)。和上面的式子对照,尾数位表示a,指数位表示b。这里尾数位的小数点默认在第一位最高位以后,以float为例,即尾数位最大表示的数为1.1111111111111111111111(二进制表示);不超过2。

例如 float 23位尾数位 即换算成十进制最大为2^23=8388608 所以float的精度位6-7位,6位精度可以保证,7位精度只能表示部分。
double 同理,精度为15-16位,15位精度可以保证正确,16位精度只能表示部分。

下面看float和double可以表示的最大值和最小值(这里最小值指最接近零的值)

float 理论上能表示的最大值:符号位为正 指数位最大127 尾数位全为1
即(2-2^22)^127 = 3.4028e+38
理论上最小值:(2-2^22)^-128 = 5.8776e-39

double 类型同样方法可以算的,不再赘述。

当然这只是理论值,具体数值在<float.h>头文件中有定义
打开float.h文件 可以看到看到以下代码:

#define DBL_DECIMAL_DIG 17                          // # of decimal digits of rounding precision
#define DBL_DIG 15                                  // # of decimal digits of precision
#define DBL_EPSILON 2.2204460492503131e-016         // smallest such that 1.0+DBL_EPSILON != 1.0
#define DBL_HAS_SUBNORM 1                           // type does support subnormal numbers
#define DBL_MANT_DIG 53                             // # of bits in mantissa
#define DBL_MAX 1.7976931348623158e+308             // max value
#define DBL_MAX_10_EXP 308                          // max decimal exponent
#define DBL_MAX_EXP 1024                            // max binary exponent
#define DBL_MIN 2.2250738585072014e-308             // min positive value
#define DBL_MIN_10_EXP (-307)                       // min decimal exponent
#define DBL_MIN_EXP (-1021)                         // min binary exponent
#define _DBL_RADIX 2                                // exponent radix
#define DBL_TRUE_MIN 4.9406564584124654e-324        // min positive value

#define FLT_DECIMAL_DIG 9                           // # of decimal digits of rounding precision
#define FLT_DIG 6                                   // # of decimal digits of precision
#define FLT_EPSILON 1.192092896e-07F                // smallest such that 1.0+FLT_EPSILON != 1.0
#define FLT_HAS_SUBNORM 1                           // type does support subnormal numbers
#define FLT_GUARD 0
#define FLT_MANT_DIG 24                             // # of bits in mantissa
#define FLT_MAX 3.402823466e+38F                    // max value
#define FLT_MAX_10_EXP 38                           // max decimal exponent
#define FLT_MAX_EXP 128                             // max binary exponent
#define FLT_MIN 1.175494351e-38F                    // min normalized positive value
#define FLT_MIN_10_EXP (-37)                        // min decimal exponent
#define FLT_MIN_EXP (-125)                          // min binary exponent
#define FLT_NORMALIZE 0
#define FLT_RADIX 2                                 // exponent radix
#define FLT_TRUE_MIN 1.401298464e-45F               // min positive value

查看源代码,可以看到float最大值和我们理论值相同,但最小值不一样,double类型同样如此
对于最小值是怎么算的,为什么这么算,这一点我也不是很懂,如果有大佬看到,希望大佬解释。

C/C++中各种类型intlongdoublechar表示范围(最大最小值)(转)

 1 #include<iostream>
 2 #include<string>
 3 #include <limits>
 4 using namespace std;
 5 
 6 int main()
 7 {
 8     cout << "type: \t\t" << "************size**************"<< endl;
 9     cout << "bool: \t\t" << "所占字节数:" << sizeof(bool);
10     cout << "\t最大值:" << (numeric_limits<bool>::max)();
11     cout << "\t\t最小值:" << (numeric_limits<bool>::min)() << endl;
12     cout << "char: \t\t" << "所占字节数:" << sizeof(char);
13     cout << "\t最大值:" << (numeric_limits<char>::max)();
14     cout << "\t\t最小值:" << (numeric_limits<char>::min)() << endl;
15     cout << "signed char: \t" << "所占字节数:" << sizeof(signed char);
16     cout << "\t最大值:" << (numeric_limits<signed char>::max)();
17     cout << "\t\t最小值:" << (numeric_limits<signed char>::min)() << endl;
18     cout << "unsigned char: \t" << "所占字节数:" << sizeof(unsigned char);
19     cout << "\t最大值:" << (numeric_limits<unsigned char>::max)();
20     cout << "\t\t最小值:" << (numeric_limits<unsigned char>::min)() << endl;
21     cout << "wchar_t: \t" << "所占字节数:" << sizeof(wchar_t);
22     cout << "\t最大值:" << (numeric_limits<wchar_t>::max)();
23     cout << "\t\t最小值:" << (numeric_limits<wchar_t>::min)() << endl;
24     cout << "short: \t\t" << "所占字节数:" << sizeof(short);
25     cout << "\t最大值:" << (numeric_limits<short>::max)();
26     cout << "\t\t最小值:" << (numeric_limits<short>::min)() << endl;
27     cout << "int: \t\t" << "所占字节数:" << sizeof(int);
28     cout << "\t最大值:" << (numeric_limits<int>::max)();
29     cout << "\t最小值:" << (numeric_limits<int>::min)() << endl;
30     cout << "unsigned: \t" << "所占字节数:" << sizeof(unsigned);
31     cout << "\t最大值:" << (numeric_limits<unsigned>::max)();
32     cout << "\t最小值:" << (numeric_limits<unsigned>::min)() << endl;
33     cout << "long: \t\t" << "所占字节数:" << sizeof(long);
34     cout << "\t最大值:" << (numeric_limits<long>::max)();
35     cout << "\t最小值:" << (numeric_limits<long>::min)() << endl;
36     cout << "unsigned long: \t" << "所占字节数:" << sizeof(unsigned long);
37     cout << "\t最大值:" << (numeric_limits<unsigned long>::max)();
38     cout << "\t最小值:" << (numeric_limits<unsigned long>::min)() << endl;
39     cout << "double: \t" << "所占字节数:" << sizeof(double);
40     cout << "\t最大值:" << (numeric_limits<double>::max)();
41     cout << "\t最小值:" << (numeric_limits<double>::min)() << endl;
42     cout << "long double: \t" << "所占字节数:" << sizeof(long double);
43     cout << "\t最大值:" << (numeric_limits<long double>::max)();
44     cout << "\t最小值:" << (numeric_limits<long double>::min)() << endl;
45     cout << "float: \t\t" << "所占字节数:" << sizeof(float);
46     cout << "\t最大值:" << (numeric_limits<float>::max)();
47     cout << "\t最小值:" << (numeric_limits<float>::min)() << endl;
48     cout << "size_t: \t" << "所占字节数:" << sizeof(size_t);
49     cout << "\t最大值:" << (numeric_limits<size_t>::max)();
50     cout << "\t最小值:" << (numeric_limits<size_t>::min)() << endl;
51     cout << "string: \t" << "所占字节数:" << sizeof(string) << endl;
52     // << "\t最大值:" << (numeric_limits<string>::max)() << "\t最小值:" << (numeric_limits<string>::min)() << endl;
53     cout << "type: \t\t" << "************size**************"<< endl;
54     return 0;
55 }

技术分享

 

以上结果已经很明白了,一下补充说明几点:

概念、整型:表示整数、字符和布尔值的算术类型合称为整型(integral type)。

关于带符号与无符号类型:整型 int、stort  和  long 都默认为带符号型。要获得无符号型则必须制定该类型为unsigned,比如unsigned long。unsigned int类型可以简写为unsigned,也就是说,unsigned后不加其他类型说明符就意味着是unsigned int。

一字节表示八位,即:1byte = 8 bit;

int: 4byte =  32 bit 有符号signed范围:2^31-1 ~ -2^31即:2147483647 ~ -2147483648无符号unsigned范围:2^32-1 ~ 0即:4294967295 ~ 0

long: 4 byte = 32 bit 同int型

double: 8 byte = 64 bit 范围:1.79769e+308 ~ 2.22507e-308

long double: 12 byte = 96 bit 范围: 1.18973e+4932 ~ 3.3621e-4932

float: 4 byte = 32 bit 范围: 3.40282e+038 ~ 1.17549e-038

int、unsigned、long、unsigned long 、double的数量级最大都只能表示为10亿,即它们表示十进制的位数不超过10个,即可以保存所有9位整数。而short只是能表示5位;

 

另外对于浮点说而言:使用double类型基本上不会有错。在float类型中隐式的精度损失是不能忽视的,二双精度计算的代价相对于单精度可以忽略。事实上,在有些机器上,double类型比float类型的计算要快得多。float型只能保证6位有效数字,而double型至少可以保证15位有效数字(小数点后的数位),long double型提供的精度通常没有必要,而且还要承担额外的运行代价。

double是8字节共64位,其中小数位占52位,2-^52=2.2204460492503130808472633361816e-16,量级为10^-16,故能够保证2^-15的所有精度。

在有些机器上,用long类型进行计算所付出的运行时代价远远高于用int类型进行同样计算的代价,所以算则类型前要先了解程序的细节并且比较long类型与int类型的实际运行时性能代价。

转自:http://blog.csdn.net/xuexiacm/article/details/8122267

技术分享
技术分享
技术分享

以上是关于C/C++ 数据类型 表示最大 最小数值 探讨的主要内容,如果未能解决你的问题,请参考以下文章

MACD ,DIFF, DEA最大最小数值是多少?

integer在数据类型中代表啥?

JS数据类型

C语言数值范围最大的数据类型(即能输出最大值)是啥?还有怎么用printf函数表示?

Qt6-数值数据类型

Java(C#)基础差异-语法