int64 or double

  • Thread starter Thread starter cj
  • Start date Start date
C

cj

VB2003. I need a large positive integer. Which is larger int64 or double?

I see int64 also apparently is known as long and will hold
-9,223,372,036,854,775,808 through 9,223,372,036,854,775,807.

But I'm not good with the E+??? notation so when I'm told double holds
-1.79769313486231570E+308 through
-4.94065645841246544E-324 for negative values; 4.94065645841246544E-324
through 1.79769313486231570E+308 for positive values.

What does that mean? is -1.79769313486231570E+308 =
-1.79769313486231570 X whatever 1 with 308 zeros behind it is?

Plus double doesn't seem to hold 1, 2, 3, 4, 5 etc cause it gives two
ranges.

Sorry, I always felt math was for the computer to figure out not me.
 
Double.MaxValue should be large enough.

the +308 means how many times you have to shift the decimal period to
the right (like if you multiply times 10 raised to 308). Try writing
this:
MsgBox(1E1)

in your compiler and see what happens ;-)

-t
 
cj said:
VB2003. I need a large positive integer. Which is larger int64 or
double?

Double is larger - but it lacks the precision of integer
variables. Integers are exact. Floating point numbers
are only close approximations. So, do you need an exact representation or
will an approximation do?
I see int64 also apparently is known as long and will
hold -9,223,372,036,854,775,808 through 9,223,372,036,854,775,807.

Is this large enough? If it is, use it. If not take a look at the
Decimal type as well as Double.
But I'm not good with the E+??? notation so when I'm told double holds
-1.79769313486231570E+308 through
-4.94065645841246544E-324 for negative values; 4.94065645841246544E-324
through 1.79769313486231570E+308 for positive values.

What does that mean? is -1.79769313486231570E+308 = -1.79769313486231570
X whatever 1 with 308 zeros behind it is?

Plus double doesn't seem to hold 1, 2, 3, 4, 5 etc cause it gives two
ranges.

Sorry, I always felt math was for the computer to figure out not me.

How will you know if the computer is giving you the right answer?
 
Charles Appel said:
Double is larger - but it lacks the precision of integer
variables. Integers are exact. Floating point numbers
are only close approximations. So, do you need an exact representation or
will an approximation do?


Is this large enough? If it is, use it. If not take a look at the
Decimal type as well as Double.


How will you know if the computer is giving you the right answer?

--
Charles Appel
http://charlesappel.home.mindspring.com/
Home of Chuck's Poker Libraries for Delphi,
Chuck's Video Poker and Chuck's Toys

In addition to Charles' comments...
Note that while a Double can have in excessive 300 digits of "precision",
only the first 16 or so digits are "accurate". This can lead to a very long
discussion, but while you might be able to get a very long number, it is
really only an approximation, of which the first 16 digits or so are
accurate.
Note how they described the limits:
1.79769313486231570E+308 for positive values
They use that notation for a reason. Only the digits listed could be
considered close to accurate, the other 291 digits it can "display" are only
an approximation.

You started by saying that you need a very large positive Integer. Well, if
that is what you need, then you should stick with Integers. Going back and
forth can cause you to lose accuracy.

Gerald
 
Just how 'large' an integer do you actually need?

To put the upper limit for an Int64 (Long) into perspective, it is
approximately 184 million times the approximate human population of the
earth.

It also equates to the number of miles in aproxiamately 1.571 million light
years.

If you consider to represent days, it also equates to aproxiamately 1.262
million times the number of days since the big bang.
 
While I'm on the subject why would anyone use a floating point number
(double or single) if they're inaccurate? Why not use decimal? Other
than the decimal takes 16 bytes vs the doubles 8.

Also I'm still not sure why double and single list the values they
accept in two ranges one for each side of 0. Do they not accept values
around 0? I'm sure they do but the documentation doesn't make sense to me.

ie: -1.79769313486231570E+308 through
 
Thanks for putting it into perspective. The answer is I don't really
know how big a number I will need. This is a counter that counts up but
I really don't know how fast as it will be based on usage. Being
careful makes me try for a type that'll hold a number it'll never hit or
perhaps I can reset it to 0 at some value but I'm not sure yet. Frankly
I'll have to do some thinking on that. double, decimal are I'm sure
large enough I wouldn't have to worry about reseting it. Frankly a
integer might be ok but I'd probably have to put in a reset just in case.

anyway thinking about all this makes me wonder about how they all fit
and which ones I'll probably use in the future. mostly I use decimal
and integer now.
 
The important thing is, for each range, to look at the signs of the
exponents.

The sign of the exponent indicates the direction in which to move the
decimal point.

+ means move the decimal to the right

- means move the decimal point to the left

To simplfy it for demonstration purposes let's take a floating point type
that allows the ranges:

-1.79E+3 to -4.94E-3
and
4.94E-3 to 1.79E+3

-1.79E+3 equates to -1790
-4.94E-3 equates to -0.00494
4.94E-3 equates to 0.00494
1.79E+3 equates to 1790

Remembering that not every number can be represented exactly in floating
point, you can see that we have ranges of:

-1790 through -0.00494 negative values
and
0.00494 through 1790 negative values

1790 is the upper limit, -1790 is the lower limit and the closest
representations of 0 that we can achieve are 0.00494 and -0.00494.

Now, extrapolate that example up to the Double type and you can see that the
ranges are:

-1.79769313486231570E+308 through -4.94065645841246544E-324 for negative
values
and
4.94065645841246544E-324 through 1.79769313486231570E+308 for positive
values

This can be rewritten as:


-179769313486231570[...300 zeroes...]00000000
through
-0.000000[...310 zeroes...]000494065645841246544
for negative values
and
0.000000[...310 zeroes...]000494065645841246544
through
179769313486231570[...300 zeroes...]00000000
for positive values

This shows that 0 cannot be represented exactly as a Double and the closest
representations of 0 that can be achieved are actually:

-0.000000[...310 zeroes...]000494065645841246544
and
0.000000[...310 zeroes...]000494065645841246544

Now, when it comes to dealing with the Decimal type, it holds a signed
128-bit (16-byte) value representing a 96-bit (12-byte) integer number
scaled by a variable power of 10.

The scaling factor specifies the number of digits to the right of the
decimal point and ranges from 0 through 28.

With a scale of 0 (no decimal places), the largest possible value is
+/-79,228,162,514,264,337,593,543,950,335
(+/-7.9228162514264337593543950335E+28).

With 28 decimal places, the largest value is
+/-7.9228162514264337593543950335, and the smallest nonzero value is
+/-0.0000000000000000000000000001 (+/-1E-28).

As you can see, for each decimal place that you have, you lose one integral
place and vice-versa.

With no decimal places you can have the equivalent of a 29 digit number with
a range of +79,228,162,514,264,337,593,543,950,335
to -79,228,162,514,264,337,593,543,950,335.

This is 10 digits wider than an Int64 (Long) and the maximum value is
approximately 8.5 bollions times larger.
 
OK. The use you have described puts it into perspective straight away.

If an Int32 counter is incremented once per second, 24/7 forever then it
will blow out early in the 69th year

If an Int64 counter is incremented once per second, 24/7 forever then it
will blow out early in the 292,271,024th millenium

If an Int32 counter is incremented once per millisecond, 24/7 forever then
it will blow out early in the 5th year

If an Int64 counter is incremented once per millisecond, 24/7 forever then
it will blow out early in the 4,872 millenium

If a Decimal (with 0 decimal places) counter is used then the blow out point
will be considerably longer.

If you expect the counter to be incremented no more frequently than once per
millisecond and don't expect it to keep counting for more than 4 years
without being reset then an Int32 (Integer) will suffice.
 
If you use it for a counter, you should definitely use an integer data
type, not a floating point type.

When you reach the limit of an integer, you get an overflow, but when
you reach the limit of a floating point number, it just stops counting,
as an increase of one has become too small to make a difference.

Also, an integer can count longer than a floating point number of the
same size.

The number of bits that a double and an int64 occupies are the same. In
the int64, 63 bits are used for the number, and one bit for the sign. In
a double, 52 bits are used for the number, 11 bits for the exponent, and
one bit for the sign. That means that an int64 can hold a number that is
2048 times larger than the number that a double accurately can handle.
For the use as a counter, the 11 bits used for exponent are wasted.
 
Whow! You do a great job of explaining this. I understand now. Just
the last question. Why would anyone want to use a imprecise number
(floating point)? Well especially when you can do it right.

Stephany said:
The important thing is, for each range, to look at the signs of the
exponents.

The sign of the exponent indicates the direction in which to move the
decimal point.

+ means move the decimal to the right

- means move the decimal point to the left

To simplfy it for demonstration purposes let's take a floating point type
that allows the ranges:

-1.79E+3 to -4.94E-3
and
4.94E-3 to 1.79E+3

-1.79E+3 equates to -1790
-4.94E-3 equates to -0.00494
4.94E-3 equates to 0.00494
1.79E+3 equates to 1790

Remembering that not every number can be represented exactly in floating
point, you can see that we have ranges of:

-1790 through -0.00494 negative values
and
0.00494 through 1790 negative values

1790 is the upper limit, -1790 is the lower limit and the closest
representations of 0 that we can achieve are 0.00494 and -0.00494.

Now, extrapolate that example up to the Double type and you can see that the
ranges are:

-1.79769313486231570E+308 through -4.94065645841246544E-324 for negative
values
and
4.94065645841246544E-324 through 1.79769313486231570E+308 for positive
values

This can be rewritten as:


-179769313486231570[...300 zeroes...]00000000
through
-0.000000[...310 zeroes...]000494065645841246544
for negative values
and
0.000000[...310 zeroes...]000494065645841246544
through
179769313486231570[...300 zeroes...]00000000
for positive values

This shows that 0 cannot be represented exactly as a Double and the closest
representations of 0 that can be achieved are actually:

-0.000000[...310 zeroes...]000494065645841246544
and
0.000000[...310 zeroes...]000494065645841246544

Now, when it comes to dealing with the Decimal type, it holds a signed
128-bit (16-byte) value representing a 96-bit (12-byte) integer number
scaled by a variable power of 10.

The scaling factor specifies the number of digits to the right of the
decimal point and ranges from 0 through 28.

With a scale of 0 (no decimal places), the largest possible value is
+/-79,228,162,514,264,337,593,543,950,335
(+/-7.9228162514264337593543950335E+28).

With 28 decimal places, the largest value is
+/-7.9228162514264337593543950335, and the smallest nonzero value is
+/-0.0000000000000000000000000001 (+/-1E-28).

As you can see, for each decimal place that you have, you lose one integral
place and vice-versa.

With no decimal places you can have the equivalent of a 29 digit number with
a range of +79,228,162,514,264,337,593,543,950,335
to -79,228,162,514,264,337,593,543,950,335.

This is 10 digits wider than an Int64 (Long) and the maximum value is
approximately 8.5 bollions times larger.



cj said:
While I'm on the subject why would anyone use a floating point number
(double or single) if they're inaccurate? Why not use decimal? Other
than the decimal takes 16 bytes vs the doubles 8.

Also I'm still not sure why double and single list the values they accept
in two ranges one for each side of 0. Do they not accept values around 0?
I'm sure they do but the documentation doesn't make sense to me.

ie: -1.79769313486231570E+308 through
 
cj said:
Whow! You do a great job of explaining this. I understand now. Just the
last question. Why would anyone want to use a imprecise number (floating
point)? Well especially when you can do it right.

Doubles take up less space than Decimals and are
generally accurate enough within their limitations.
I'd have to test this, but my guess is they are also
faster than Decimals. How much accuracy you need
depends on the specific problem. The Lockheed
SR-71 was designed in the 1950s using slide
rules. AFAIK, it is still the fastest jet aircraft in the
world.
 
Excellent explanation!

To address the question of why one would use a Floating Point value...
It depends a great deal upon what you need. Take geometric operations for
example.
If you are using PI and other multiplications / divisions, etc. where you
really need floating point values, Doubles make sense. However, programmers
need to consider the accuracy and write their code in such a way that the
final result will be "accurate enough". This sometimes means doing some
interesting things, one of which is ensuring that you perform your
calculations by grouping variables of similiar magnitude to minimize
rounding errors.

Additionally, the implementation of a Double is currently significantly
faster than Decimal due to very complex implementation details. I suspect
that at some point in the future, a Decimal datatype will be implemented
natively in hardware. At that point, a version of Decimal might unseat
Double for many applications.

An interesting bit of trivia...
While most CAD applications use the Double datatype for storing coordinates,
some of the fastest and best ones out there actually use Integers for
storage units. Interim math is performed using Doubles when needed, but
underneath the hood they are natively stored as long Integers. While at
first this may seem contrary to good sense due to rounding errors, in
implementation it gives some significant advantages. First, when Doubles are
not required, Integer operations are much faster. But when it comes to
rounding errors and such, when you base your system on Integers you can
almost exactly know and/or control the accuracy tolerance.

Gerald

Stephany Young said:
The important thing is, for each range, to look at the signs of the
exponents.

The sign of the exponent indicates the direction in which to move the
decimal point.

+ means move the decimal to the right

- means move the decimal point to the left

To simplfy it for demonstration purposes let's take a floating point type
that allows the ranges:

-1.79E+3 to -4.94E-3
and
4.94E-3 to 1.79E+3

-1.79E+3 equates to -1790
-4.94E-3 equates to -0.00494
4.94E-3 equates to 0.00494
1.79E+3 equates to 1790

Remembering that not every number can be represented exactly in floating
point, you can see that we have ranges of:

-1790 through -0.00494 negative values
and
0.00494 through 1790 negative values

1790 is the upper limit, -1790 is the lower limit and the closest
representations of 0 that we can achieve are 0.00494 and -0.00494.

Now, extrapolate that example up to the Double type and you can see that the
ranges are:

-1.79769313486231570E+308 through -4.94065645841246544E-324 for negative
values
and
4.94065645841246544E-324 through 1.79769313486231570E+308 for positive
values

This can be rewritten as:


-179769313486231570[...300 zeroes...]00000000
through
-0.000000[...310 zeroes...]000494065645841246544
for negative values
and
0.000000[...310 zeroes...]000494065645841246544
through
179769313486231570[...300 zeroes...]00000000
for positive values

This shows that 0 cannot be represented exactly as a Double and the closest
representations of 0 that can be achieved are actually:

-0.000000[...310 zeroes...]000494065645841246544
and
0.000000[...310 zeroes...]000494065645841246544

Now, when it comes to dealing with the Decimal type, it holds a signed
128-bit (16-byte) value representing a 96-bit (12-byte) integer number
scaled by a variable power of 10.

The scaling factor specifies the number of digits to the right of the
decimal point and ranges from 0 through 28.

With a scale of 0 (no decimal places), the largest possible value is
+/-79,228,162,514,264,337,593,543,950,335
(+/-7.9228162514264337593543950335E+28).

With 28 decimal places, the largest value is
+/-7.9228162514264337593543950335, and the smallest nonzero value is
+/-0.0000000000000000000000000001 (+/-1E-28).

As you can see, for each decimal place that you have, you lose one integral
place and vice-versa.

With no decimal places you can have the equivalent of a 29 digit number with
a range of +79,228,162,514,264,337,593,543,950,335
to -79,228,162,514,264,337,593,543,950,335.

This is 10 digits wider than an Int64 (Long) and the maximum value is
approximately 8.5 bollions times larger.



cj said:
While I'm on the subject why would anyone use a floating point number
(double or single) if they're inaccurate? Why not use decimal? Other
than the decimal takes 16 bytes vs the doubles 8.

Also I'm still not sure why double and single list the values they accept
in two ranges one for each side of 0. Do they not accept values around 0?
I'm sure they do but the documentation doesn't make sense to me.

ie: -1.79769313486231570E+308 through
 
Back
Top