Using the Built-in Arithmetic Types

C++ Primer 4/e has a good advice : ”

The number of integral types in C++ can be bewildering. C++, like C, is designed to let programs get close to the hardware when necessary, and the integral types are defined to cater to the peculiarities of various kinds of hardware. Most programmers can (and should) ignore these complexities by restricting the types they actually use.

In practice, many uses of integers involve counting. For example, programs often count the number of elements in a data structure such as a vector or an array. We’ll see in Chapters 3 and 4 that the library defines a set of types to use when dealing with the size of an object. When counting such elements it is always right to use the library-defined type intended for this purpose. When counting in other circumstances, it is usually right to use an unsigned value. Doing so avoids the possibility that a value that is too large to fit results in a (seemingly) negative result.

When performing integer arithmetic, it is rarely right to use shorts. In most programs, using shorts leads to mysterious bugs when a value is assigned to a short that is bigger than the largest number it can hold. What happens depends on the machine, but typically the value “wraps around” so that a number too large to fit turns into a large negative number. For the same reason, even though char is an integral type, the char type should be used to hold characters and not for computation. The fact that char is signed on some implementations and unsigned on others makes it problematic to use it as a computational type.

On most machines, integer calculations can safely use int. Technically speaking, an int can be as small as 16 bitstoo small for most purposes. In practice, almost all general-purpose machines use 32-bits for ints, which is often the same size used for long. The difficulty in deciding whether to use int or long occurs on machines that have 32-bit ints and 64-bit longs. On such machines, the run-time cost of doing arithmetic with longs can be considerably greater than doing the same calculation using a 32-bit int. Deciding whether to use int or long requires detailed understanding of the program and the actual run-time performance cost of using long versus int.

Determining which floating-point type to use is easier: It is almost always right to use double. The loss of precision implicit in float is significant, whereas the cost of double precision calculations versus single precision is negligible. In fact, on some machines, double precision is faster than single. The precision offered by long double usually is unnecessary and often entails considerable extra run-time cost.”

And chinese translation is easy to read :‘C++ 整数型别(integral types) 的数量可能让人困惑。C++和 Cㄧ样,被设计用来让程式必要时能接近硬体,而其整数型别便是被定义来迎合各种硬体特性。大部分程式员可以(也应该)忽略这些复杂特性,只使用他们实际需要的型别。

现实中很多整数用于计数。例如程式通常会计算像vector或array资料结构内的元素个数。我们将在第3,4章看到程式库定义了一组型别用以处理上述物件的大小(亦即元素的个数)。计算这些元素个数时,使用程式库专门为此而定义的型别是对的。其他情形下计数通常应该使用unsigned数值,这可避免数值太大而产生(表面上看起来是)负直的可能性。

执行整数算术时,shorts几乎不会是正确的选择。在大部分程式中,如果把“超过shorts所能存放的最大值”的数值赋予一个short,会导致神秘臭虫。实际上发生什么事取决于机器,但通常那个值会“折回来”(wraps around),使一个过大值变成一个大负数。同样道理,即使char是个整数相关型别,它仍应该用来存放字元而非用来计算。char在某些编译器上是signed而其他编译器视之为unsigned,这一事实使得用char来计算会有问题。

在大部份机器上,int可被安全地用于整数计算。严格说来一个int可以小至16 bits,这对任何目的来说都未免太小。但现实中几乎所有泛用型机器的ints都有32 bits,和long相同。在这种机器上,long算术的执行期成本可能比32-bit int作相同计算的成本大很多。究竟该使用int 或 long,必须先对程式有详细了解并实际比较使用long或int的执行期成本。

决定使用哪一种浮点数型别就简单多了:使用double几乎总是对的。float隐含的精度遗失很显著,而倍精度和单精度计算的成本差距简直可被忽略。事实上在某些机器,倍精度比单精度还快。程式通常不需要long double这样的精确度,而且执行期成本通常多很多。’

原来unsigned int是这么好用,用double最大的困扰就是很大一串数字,但是没错精度差很多,那还是用double 的好。