6

Coming from a Java and C# background, I've learned to use int (32 bits) whenever I need a whole number, and double (64 bits) when dealing with fractional values. Most methods from their respective frameworks (JVM and .NET) usually expect these two types.

My question is, why don't we use both long and double for consistency? I know that having 64 bits of precision in integers is not needed most of the time, but then again, we don't usually need 64 bits of precision in floating point numbers, or do we?

What is the reasoning behind this, if any?

  • "It might seem like a float would be enough for what anybody would reasonably need, but it's not... Actually, 64-bit doubles with their 15 decimal digits aren't good enough for many applications..." (Why do you need float/double?) – gnat Dec 23 '15 at 19:18
  • Coming from a C background, I've learned to use BigDecimal for floating-point numbers, since rounding and comparing FP values is so problematic. – TMN Dec 23 '15 at 19:29
  • 1
    @TMN I'm not sure that a type that throws when you try to compute 1/3 is the solution for everyting. – svick Dec 23 '15 at 22:53
5

Range vs. Precision

One thing is that I'd contest the idea that the most common floating-point number uses a 64-bit DPFP (double-precision floating-point) representation.

At least in performance-critical real-time fields like games, SPFP (single-precision floating-point) is still far more common, since approximation and speed there is preferable to utmost accuracy.

Yet perhaps one way to look at this is that a 32-bit int represents a range of 2^32 integers (~4.3 billion). The most common use of integers is probably going to be as indices to elements, and that's a pretty healthy range of elements that would be difficult to exceed without exceeding the memory available with today's hardware *.

* Note that out of memory errors can occur when allocating/accessing a single, contiguous 4 gigabyte block even with 30 gigabytes free, e.g., due to the contiguity requirements of that block.

A 32-bit integer isn't always more efficient at the instruction level, but it tends to generally be more efficient when aggregated into an array, e.g., as it requires half the memory (more indices that can fit into a single page/cache line, e.g.).

Also note that as Lightness Races in Orbit points out, it's not necessarily even true from a broad perspective that 32-bit integers are more commonly-used. I have my narrow perspective coming from a field where 32-bit ints are often aggregated by the hundreds of thousands to millions as indices into another structure -- there the halving in size can help a lot.

Now 64-bit DPFP might be used a whole lot more than 64-bit integers in some contexts. There the extra bits are adding precision rather than range. A lot of applications can demand precision, or at least have a much easier time programming with extra precision available. So that's probably why 64-bit DPFPs might be more common than 64-bit integers in some areas, and why int might still be 32-bits in many scenarios even on 64-bit platforms.

  • I'd contest the idea that the most common integral data type is 32 bits wide, too, at least in programs written today on commodity hardware. 64-bit platforms are so widespread now. – Lightness Races in Orbit Dec 23 '15 at 19:08
  • 1
    @I​​​​​​​​​​​​​ke: Thing is I suspect much software just uses int and long without really caring what the range is ... and such software is, I believe, predominantly using 64-bit integers in both cases nowadays. – Lightness Races in Orbit Dec 23 '15 at 19:13
  • 2
    Hmm I stand corrected; apparently int is generally still 32-bit, largely to avoid introducing bugs in just that sort of code. Ok well you've still got size_t and long. – Lightness Races in Orbit Dec 23 '15 at 19:14
  • 1
    @LightnessRacesinOrbit Ah I see, I'm extremely biased since I often work in codebases that aggregate integers into some data structure with a concern over the total memory size. I tried to make my answer as neutral as possible. – user204677 Dec 23 '15 at 19:14
  • 1
    @I​​​​​​​​​​​​​ke: Personally I make all my types explicitly-sized too. But you and I are doubtless abnormal. :) – Lightness Races in Orbit Dec 23 '15 at 19:16
3

Well, int and double is a Java thing. For example, in Objective-C and Swift you would use NSInteger or Int, which is 32 bit on a 32 bit machine and 64 bit on a 64 bit machine. Big enough to count any number of items that might be in memory. What is definitely useful is to use the same type almost everywhere, unless in a particular situation you need something else.

Java tries to have code that runs the same on any implementation, so they think you should use the same type independent of the machine you are using, and that the type should have the same number of bits independent of the machine. Objective-C and Swift (and C, C++ as well) have a different point of view.

Integers are mostly used for counting things, and usually you don't have that many things to count. Floating point arithmetic needs precision, and 32 bit floating point often doesn't give you enough precision. Using 64 bit double everywhere gives you a fighting chance to always have enough precision, without being a specialist in floating-point arithmetic. float doesn't.

But what consistency would using long and double give you? Integers and floating point numbers are not the same thing. There is no need for them to have consistent bit size. I use 2D points and rectangles a lot. So for consistency, should they also be 64 bits? Points having 32 bit per component, and rectangles having 16? Of course not. No consistency needed.

  • This is a very nice answer explaining the JVM side of it of keeping the size of each type the same regardless of the platform. – user204677 Dec 23 '15 at 20:52
2

short, int, single and double are the same size in java as they are in most common C compilers for 32-bit and 64-bit platforms and C like java clearly considers int to be the main integer type and double to be the main floating point type. I think it's reasonable to say that Java inherited this convention from common C compilers at the time.

Integers are usually used for counting or indexing stuff.It's pretty rare (though not unheard of) to need to count or index more than 2 billion of something. Indeed prior to C99 you had to use vendor specific types if you wanted a 64-bit integer.

Floating point numbers are usuaully used as an approximation of the real numbers. Single precision is good enough much of the time but it's not hard to find problems where it causes an unacceptable amount of rounding error. I expect demand from scientific computing is what drove double precision floating point support to be ubiquitous long before 64-bit integer support was.

What I do find curious is that C seems to encourage use of double while fortran seems to encourage the use of single precision.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.