views:

416

answers:

8

I want to use lua (that internally uses only doubles) to represent a integer that can't have rounding errors between 0 and 2^64-1 or terrible things will happen.

Is it possible to do so?

+13  A: 

No

At least some bits of a 64-bit double must be used to represent the exponent (position of the binary point), and hence there are fewer than 64-bits available for the actual number. So no, a 64-bit double can't represent all the values a 64-bit integer can (and vice-versa).

stusmith
Well - that's true as long as you have no mapping function between the floating point number and 64b integer. You can "represent" the number as a different floating point number. It's just not practical :)
viraptor
Even the impractical solution might not work - for instance a signalling NaN (SNaN) value might trigger an exception if handled within Lua (no idea if that's true - but it might).
stusmith
Some values for doubles are denormalized - if your language might renormalize them without warning, you can't safely fit 64 bits of information into them.
bdonlan
+4  A: 

The double is a 64bit type itself. However you lose 1 bit for the sign and 11 for the exponent.

So the answer is no: it can't be done.

Toad
you gain one bit because the highest one is always nonzero, ie the precision is `total_bits - sign_bit - exp_bits + implicit_bit = 64 - 1 - 11 + 1 = 53`
Christoph
I don't understand your explanation. I do understand that one could 'misuse' the sign bit for an increased numeric range. (So basically using the negative numbers to increase the positive range)
Toad
@reiner. For instance, the binary decimal 0.01...(51 more 1s)...1 is exactly representable in an IEEE double, even though it has 53 significant figures. It is represented by an exponent of -2 (taking 11 bits), a sign of 0 (taking 1 bit), and a mantissa of 1...(50 1s)...1 (taking 52 bits). The first 1 isn't stored anywhere, it's assumed. You would always choose an exponent such that the "first" bit of the mantissa is 1, so that first bit is just left out. The exception is denorms, which are handled slightly differently (or not at all).
Steve Jessop
@reinier: IEEE 754 doubles have 23 for the exponent, don't they? 11-bit exponents are for floats. Not that it changes the spirit of your argument :-)
Arthur Reutenauer
hmm.. you might be right. I know Microsoft uses this: The double type contains 64 bits: 1 for sign, 11 for the exponent, and 52 for the mantissa. Its range is +/–1.7E308 with at least 15 digits of precision. source: http://msdn.microsoft.com/en-us/library/e02ya398%28VS.80%29.aspx
Toad
@Arthur: IEEE 754 doubles have an 11 bit exponent field. Single-precision has an 8 bit exponent field. The only 23 bit field in any 754 fixed width type is the significand field of a single-precision number.
Stephen Canon
A: 

i know nothing about lua
but if you could figure out how to perform bitwise manipulation of the float in this language, you could in theory make a wrapper class that took your number in the form of a string and set the bits of the float in the order which represents the number you gave it
a more practical solution would be to use some bignum library

adi92
+2  A: 

From memory, a double can represent a 53-bit signed integer exactly.

dreamlax
+1  A: 

On 64 bits you can only store 2^64 different codes. This means that a 64-bit type which can represent 2^64 integers doesn't have any place for representing something else, such as floating point numbers.

Obviously double can represent a lot of non-integers numbers, so it can't fit your requirements.

Bastien Léonard
+5  A: 

Even though you've gotten some good answers to your question about 64-bit types, you may still want a practical solution to your specific problem. The most reliable solution I know of is to build Lua 5.1 with the LNUM patch (also known as the Lua integer patch) which can be downloaded from LuaForge. If you aren't planning on building Lua from the C source, there is at least one pure Lua library that handles 64-bit signed integers -- see the Lua-users wiki.

Kyle Pierce
Thanks for the references, +1.
Andrew Y
+1  A: 

No, you cannot use Double to store 64-bit integers without losing precision.

However, you can apply a Lua patch that adds support for true 64-bit integers to the Lua interpreter. Apply the LNUM patch to your Lua source and recompile.

Aaron Saarela
A: 

IEEE 754 double cannot represent 64-bit integers exactly. It can, however, represent exactly every 32-bit integer value.

Jarek Przygódzki