views:

2862

answers:

13

C++ offers three floating point types: float, double, and long double. I infrequently use floating-point in my code, but when I do, I'm always caught out by warnings on innocuous lines like

float PiForSquares = 4.0;

The problem is that the literal 4.0 is a double, not a float - Which is irritating.

For integer types, we have short int, int and long int, which is pretty straightforward. Why doesn't C just have short float, float and long float? And where on earth did "double" come from?

EDIT: It seems the relationship between floating types is similar to that of integers. double must be at least as big as float, and long double is at least as big as double. No other guarantees of precision/range are made.

+15  A: 

You probably knew this, but you can make literal floats/long doubles

 float f = 4.0f;
 long double f = 4.0l;

Double is the default because thats what most people use. Long doubles may be overkill or and floats have very bad precision. Double works for almost every application.

Why the naming? One day all we had was 32 bit floating point numbers (well really all we had was fixed point numbers, but I digress). Anyway, when floating point became a popular feature in modern architectures, C was probably the language dujour then, and the name "float" was given. Seemed to make sense.

At the time, double may have been thought of, but not really implemented in the cpu's/fp cpus of the time, which were 16 or 32 bits. Once the double became used in more architectures, C probably got around to adding it. C needed something a name for something twice the size of a float, hence we got a double. Then someone needed even more precision, we thought he was crazy. We added it anyway. The name quadtuple(?) was overkill. Long double was good enough, and nobody made a lot of noise.

Part of the confusion is that good-ole "int" seems to change with the time. It used to be that "int" meant 16 bit integer. Float, however, is bound to the IEEE std as the 32-bit IEEE floating point number. For that reason, C kept float defined as 32 bit and made double and long double to refer to the longer standards.

Doug T.
Thanks. but if "float" was the original type, why are literals double? And I think the IEEE explanantion is nice - but wrong: IEEE-754 was published in '85...
Roddy
Well was float part of the C std before 1985? Its very likely that people used fixed-point arithmetic for a long time.
Doug T.
IIRC, the terms "float" for 32-bit float and "double" for 64-bit double go way back to the 60's, before C was conceived. Probably originated with the IBM 360 architecture
Die in Sente
"Very bad percision" - tell that to your video card manufacturer. all GPU and basically all graphics ever is performed with floats.
shoosh
C89 float might be IEE754, but need not to.
MSalters
Very good explanation. You might want to add that some libraries/languages call a float a single.
Jonathan C Dickinson
+2  A: 

First, these names are not specific to C++, but are pretty much common practice for any floating-point datatype that implements IEEE 754.

The name 'double' refers to 'double precision', while float is often said to be 'single precision'.

jalf
http://en.wikipedia.org/wiki/IEEE_754-1985Nice idea, but IEEE-754 postdates C by at least a decade...
Roddy
+1  A: 

The two most common floating point formats use 32-bits and 64-bits, the longer one is "double" the size of the first one so it was called a "double".

Robert Gamble
A: 

double is short for "double precision". long double, I guess, comes from not wanting to add another keyword when a floating-point type with even higher precision started to appear on processors.

erikkallen
A: 

Okay, historically here is the way it used to be:

The original machines used for C had 16 bit words broken into 2 bytes, and a char was one byte. Addresses were 16 bits, so sizeof(foo*) was 2, sizeof(char) was 1. An int was 16 bits, so sizeof(int) was also 2. Then the VAX (extended addressing) machines came along, and an address was 32 bits. A char was still 1 byte, but sizeof(foo*) was now 4.

There was some confusion, which settled down in the Berkeley compilers so that a short was now 2 bytes and an int was 4 bytes, as those were well-suited to efficient code. A long became 8 bytes, because there was an efficient addressing method for 8-byte blocks --- which were called double words. 4 byte blocks were words and sure enugh, 2-byte blocks were halfwords.

The implementation of floating point numbers were such that they fit into single words, or double words. To remain consistent, the doubleword floating point number was then called a "double".

Charlie Martin
I don't think this is correct. All of this is the history of integers... every history of floating point I've heard says "double" means "double precision".
Qwertie
+1  A: 

A double is named such because it is double the "precision" of a float. Really, what this means is that it uses twice the space of a floating point value -- if your float is a 32-bit, then your double will be a 64-bit.

The name double precision is a bit of a misnomer, since a double precision float has a precision of the mantissa of 52-bits, where a single precision float has a mantissa precision of 23-bits (double that is 56). More on floating point here: Floating Point - Wikipedia, including links at the bottom to articles on single and double precision floats.

The name long double is likely just down the same tradition as the long integer vs. short integer for integral types, except in this case they reversed it since 'int' is equivalent to 'long int'.

Ed Carrel
2*23 = 46, not 56 or 52
Mr Fooz
A: 

It should be noted that double does NOT have to be able to hold values greater in magnitude than those of float; it only has to be more precise.

aib
I don't think it *has* to be more precise: It must be "no less precise" which is rather different...
Roddy
The standard gives it a smaller epsilon. 1E-5 vs. 1E-7, I think.
aib
+1  A: 

In fixed-point representation, there are a fixed number of digits after the radix point (a generalization of the decimal point in decimal representations). Contrast to this to floating-point representations where the radix point can move, or float, within the digits of the number being represented. Thus the name "floating-point representation." This was abbreviated to "float."

In K&R C, float referred to floating-point representations with 32-bit binary representations and double referred to floating-point representations with 64-bit binary representations, or double the size and whence the name. However, the original K&R specification required that all floating-point computations be done in double precision.

In the initial IEEE 754 standard (IEEE 754-1985), the gold standard for floating-point representations and arithmetic, definitions were provided for binary representations of single-precision and double-precision floating point numbers. Double-precision numbers were aptly name as they were represented by twice as many bits as single-precision numbers.

For detailed information on floating-point representations, read David Goldberg's article, What Every Computer Scientist Should Know About Floating-Point Arithmetic.

Jason
+21  A: 

The terms "single precision" and "double precision" originated in FORTRAN and were already in wide use when C was invented. On early 1970s machines, single precision was significantly more efficient and as today, used half as much memory as double precision. Hence it was a reasonable default for floating-point numbers.

long double was added much later when the IEEE standard made allowances for the Intel 80287 floating-point chip, which used 80-bit floating-point numbers instead of the classic 64-bit double precision.

Questioner is incorrect about guarantees; today almost all languages guarantee to implement IEEE 754 binary floating-point numbers at single precision (32 bits) and double precision (64 bits). Some also offer extended precision (80 bits), which shows up in C as long double. The IEEE floating-point standard, spearheaded by William Kahan, was a triumph of good engineering over expediency: on the machines of the day, it looked prohibitively expensive, but on today's machines it is dirt cheap, and the portability and predictability of IEEE floating-point numbers must save gazillions of dollars every year.

Norman Ramsey
The OP is talking about C and C++, neither of which guarantee IEEE 754.
Robert Gamble
c++ has a flag to see whether or not ieee754 is implemented: numeric_limits<double>::is_iec559
Johannes Schaub - litb
Similarly, C99 has the __STDC_IEC_559__ macro but these just test whether the implementation purports to use IEEE. What I am objecting to is the statement "Questioner is incorrect about guarantees" when C/C++ don't guarantee IEEE floating point.
Robert Gamble
I also doubt the claim that "almost all [modern] languages guarantee to implement IEEE 754 binary floating-point numbers". Of all the languages I use, I can only think of one that I know guarantees this.
Robert Gamble
"single precision" isn't really a fortran term. fortran has/had "real" and "double precision".
Roddy
+3  A: 

Literals

The problem is that the literal 4.0 is a double, not a float - Which is irritating.

With constants there is one important difference between integers and floats. While it is relatively easy to decide which integer type to use (you select smallest enough to hold the value, with some added complexity for signed/unsigned), with floats it is not this easy. Many values (including simple ones like 0.1) cannot be exactly represented by float numbers and therefore choice of type affects not only performance, but also result value. It seems C language designers preferred robustness against performance in this case and they therefore decided the default representation should be the more exact one.

History

Why doesn't C just have short float, float and long float? And where on earth did "double" come from?

The terms "single precision" and "double precision" originated in FORTRAN and were already in wide use when C was invented.

Suma
A: 

very helpful comments. I am taking C++ myself and a bit confused about the "single precision""double precision" terminologies.

A: 

They're called single-precision and double-precision because they're related to the natural size (not sure of the term) of the processor. So a 32-bit processor's single-precision would be 32 bits long, and its double-precision would be double that - 64 bits long. They just decided to call the single-precision type "float" in C.

Ray Hidayat
You're looking for the term "word size".
Jyaan
A: 

hence the %f for a float type, and a %lf for a long float which is the same as double.

EvilTeach
In the `printf` function from C, `%f` already stands for `double`, while `%Lf` stands for `long double`. For the `scanf` function, you are correct though.
Roland Illig