关于C++ numeric_limits<char>

从学习C语言开始,int类型所占字节数,以及数值范围就是一个挥之不去的问题。一开始会死记硬背一个char 1个字节,一个字节8个bit。64位机器上面一个int 4个字节,32位机器上面不一样。那时候并不知道编译器也分很多种,每一种实现的细节不一样,也不知道各家编译器是遵循C++标准委员会的标准。后来学会像编译器求证,以其输出为准,也学会向标准求证。

在一篇博客上面看到用numeric_limits 类可以方便地了解各个类型的取值范围以及占用内存,于是满心欢喜地将代码运行,发现有些问题:

#include<iostream>
#include <limits>
using namespace std;

int main()
{
    cout << "type: \t\t" << "------------------size-----------------------"<< endl;
    cout << "bool: \t\t" << "Bytes:" << sizeof(bool);
    cout << "\tMaxValue:" << (numeric_limits<bool>::max)();
    cout << "\t\tMinValue:" << (numeric_limits<bool>::min)() << endl;
    cout << "char: \t\t" << "Bytes:" << sizeof(char);
    cout << "\tMaxValue:" << (numeric_limits<char>::max)();
    cout << "\t\tMinValue:" << (numeric_limits<char>::min)() << endl;
    cout << "signed char: \t" << "Bytes:" << sizeof(signed char);
    cout << "\tMaxValue:" << (numeric_limits<signed char>::max)();
    cout << "\t\tMinValue:" << (numeric_limits<signed char>::min)() << endl;
    cout << "unsigned char: \t" << "Bytes:" << sizeof(unsigned char);
    cout << "\tMaxValue:" << (numeric_limits<unsigned char>::max)();
    cout << "\t\tMinValue:" << (numeric_limits<unsigned char>::min)() << endl;
    cout << "wchar_t: \t" << "Bytes:" << sizeof(wchar_t);
    cout << "\tMaxValue:" << (numeric_limits<wchar_t>::max)();
    cout << "\t\tMinValue:" << (numeric_limits<wchar_t>::min)() << endl;
    cout << "short: \t\t" << "Bytes:" << sizeof(short);
    cout << "\tMaxValue:" << (numeric_limits<short>::max)();
    cout << "\t\tMinValue:" << (numeric_limits<short>::min)() << endl;
    cout << "int: \t\t" << "Bytes:" << sizeof(int);
    cout << "\tMaxValue:" << (numeric_limits<int>::max)();
    cout << "\tMinValue:" << (numeric_limits<int>::min)() << endl;
    cout << "unsigned: \t" << "Bytes:" << sizeof(unsigned);
    cout << "\tMaxValue:" << (numeric_limits<unsigned>::max)();
    cout << "\tMinValue:" << (numeric_limits<unsigned>::min)() << endl;
    cout << "long: \t\t" << "Bytes:" << sizeof(long);
    cout << "\tMaxValue:" << (numeric_limits<long>::max)();
    cout << "\tMinValue:" << (numeric_limits<long>::min)() << endl;
    cout << "type: \t\t" << "************size**************"<< endl;
    return 0;
}

运行结果:

常用的int,long等类型的取值范围确实如愿显示。但是,在关于 char的判断中,有显示的问题。从使用的角度而言,其实char用于表示字符,判断大小并不合理。当然,这只是一个“完形填空”式的推导。既然显示在屏幕上的输出有问题,本着钻研精神,要弄清楚为什么。

首先是假设:

1. cout无法处理这个numeric_limit<char>::max()函数

2.numeric_limit<char>::max()的返回值并不是可显示字符。

为了验证第一点,我找到C++标准委员会的网站,找到C++14的草稿标准:

从这里看出,返回的是模板类型 T的构造函数。似乎排除了第一种可能。但标准太不具体,我在Clion上面用debug模式直接找到库文件来确认。值得一提的是编译器版本:gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.2)。

第一步:

再往下一层:

在limits的实现里面,都是再用宏定义的位操作来实现最大和最小值的获取。先看__glibcxx_digits宏定义。这里面的逻辑很简单,占用字节数乘以__CHAR_BIT__减去符号位(1位)。在char的例子里面,得出来的位数是7。从这里不妨猜测,编译器对一个字节大小的定义很有可能是基于__CHAR_BIT__的。在一篇博文看过对于古老的机器,char类型只有7bit。按照这个猜测,在描述内置int型大小的时候,就可以说一个int等于4个char。这个猜测挺有意思,不过有待考究。

进一步分析,__glicxx_min宏定义,对于传入的类型_Tp,如果有符号,就执行(_Tp)1 << _glibcxx_digits(_Tp), 没有就是(_Tp)0.

对于char型,它居然被是认为有符号的! 所以最小值的计算变成 (char)1 << 7,二进制表示10000000, -128.

一个被赋值为-128的char类型字符,恐怕并不是可显示字符。这里面的实现动机也很难理解。

花费了一个下午最终知道了一下计算的细节但是没有很了解动机,有些郁闷。改天会再解一下cout的运行,看其中再有无关联。

也希望有高人看到能够解答。

时间: 2024-11-04 23:03:47

关于C++ numeric_limits<char>的相关文章

C/C++中各种类型int、long、double、char表示范围(最大最小值)(转)

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

C++ limits头文件的用法(numeric_limits)

初学C++的时候,对这个模板很陌生,不知道它到底是做什么用的,今天拿起<C++标准程序库>,出现了它的讨论,所以决定好好研究一番. 1. numeric_limits是什么? (A)<C++标准程序库>: [cpp] view plaincop 一般来说,数值型别的极值是一个与平台相关的特性.C++标准程序库通过template numeric_limits提供这些极值,取代传统C语言,所采用的预处理常数.新的极值概念有两个优点,第一是提供更好的型别安全性,第二是程序员可借此写出一

C++标准库的数值极限numeric_limits

包含头文件:#include<limits> 它是一个模板类,它主要是把C++当中的一些内建型别进行了封装,比如说numeric_limits<int>是一个特化后的类,从这个类的成员变量与成员函数中,我们可以了解到int的很多特性:可以表示的最大值,最小值,是否是精确的,是否是有符号等等.如果用其他任意(非内建类型)来特化这个模板类,比如string,string怎么可能有最大值?我们从MSDN上可以了解到,这对string,成员变量与成员函数是没有意义的,要么返回0要么为fal

numeric_limits 模板的相关知识点

说白了,它是一个模板类,它主要是把C++当中的一些内建型别进行了封装,比如说numeric_limits<int>是一个特化后的类,从这个类的成员变量与成员函数中,我们可以了解到int的很多特性:可以表示的最大值,最小值,是否是精确的,是否是有符号等等.如果用其他任意(非内建类型)来特化这个模板类,比如string,string怎么可能有最大值?我们从MSDN上可以了解到,这对string,成员变量与成员函数是没有意义的,要么返回0要么为false. 具体的一些用法: #include <

C++之数据类型及其值的范围

C++中的常用类型有bool.char.short.int.long.double.float.string等.这些数据类型满足了我们日常变成的需求. 下面的代码用来打印出各数据类型对应的占字节数及其最大值和最小值. 1 #include<iostream> 2 #include<string> 3 #include <limits> 4 #include <climits> 5 using namespace std; 6 7 int main() 8 {

C++primer(第五版)第二章的学习笔记(也有对部分习题的解答和指出c++11特性)

算术类型分为两类:整型(字符和bool在内)和浮点型. C/C++算术类型 类型 含义 最小尺寸 bool 布尔类型 未定义 char 字符 8位 wchar_t 宽字符 16位 char16_t Unicode字符 16位 char32_t Unicode字符 32位 short 短整型 16位 int  整型 16位 long 长整型 32位 long long 长整型 64位 unsigned long 无符号长整型 32位 double 双精度浮点数 10位有效数字 long doubl

温故而知新 C++基本类型

C++基本类型大小: 在32位计算机中测试得到:sizeof(bool) == 1sizeof(char) == 1 sizeof(short) == 2sizeof(int) == 4sizeof(long) = 4sizeof(float) == 4sizeof(double) == 8 类型枚举:enum //例子: 定义一个服务器的当前状态,分别表示启动,关闭,暂停状态 enum ServerState{START, STOP, PAUSE}; 类型void*void指针可以指向任意类型

c++中各种数据类型所占字节

求各种数据类型所占用的字节数可调用sizeof函数,求各种数据类型的最大值可以调用limits标准库中的numeric_limits<T>::max(),numeric_limits<T>::min()函数 #include<iostream> #include<string> #include <limits> using namespace std; int main() { cout << "type: \t\t&qu

numeric_cast

#include <iostream> #include "boost/cast.hpp" #include "boost/limits.hpp" int main() { std::cout << std::numeric_limits<long>::max()<<std::endl; std::cout << std::numeric_limits<short>::max() <<