Window's Calculator Numbers
Have you guys ever really tried fooling around with the Window''s built-in calculator? How can it really handle numbers that large? Here''s an example. Put in 20000!. It took about 10 seconds to calculate on my computer, but the real answer came out, most likely with every digit correct. I mean, every digit, including the ones you can''t see are stored somewhere in memory. The actual answer is something like 1.819 x 10^77337. Does anyone know what kind of data structure the program is using?
ColdfireV
[email=jperegrine@customcall.com]ColdfireV[/email]
It doesn''t according to Help, but then it does something strange compared to say C++ double. Based on the comment in the Help about 1/3 I think it must do something that stores your input as you enter it literaly, i.e 1/3*4, then hit = and it computes. Though it probably is smart and goes for a stack implementation of reverse-polish notation. Anyone, other than me, ever written one those? Neato stuff.
Couple of long clips and a few comments below for those interested.
From the Calculator''s Help. (you did read it didn''t you )
*** START CLIP ***
Understanding extended precision
Extended Precision, a feature of Calculator, implies that all operations are accurate to at least 32 digits. Calculator also stores rational numbers as fractions to retain accuracy. For example, 1/3 is stored as 1/3, rather than .333. However, errors accumulate during repeated operations on irrational numbers. For example, Calculator will truncate pi to 32 digits, so repeated operations on pi will lose accuracy as the number of operations increases. >>
*** END CLIP ***
So it is only guranteed accurate to 32 digits.
I would of guessed the actual format is something like a float or double in C++. Here is some major clippage from the Visual C++ 6.0 Help (MSDN actually).
*** START CLIP ***
(i''ve tried to make the tables neat)
Type float
Floating-point numbers use the IEEE (Institute of Electrical and Electronics Engineers) format. Single-precision values with float type have 4 bytes, consisting of a sign bit, an 8-bit excess-127 binary exponent, and a 23-bit mantissa. The mantissa represents a number between 1.0 and 2.0. Since the high-order bit of the mantissa is always 1, it is not stored in the number. This representation gives a range of approximately 3.4E–38 to 3.4E+38 for type float.
You can declare variables as float or double, depending on the needs of your application. The principal differences between the two types are the significance they can represent, the storage they require, and their range. Table 3.3 shows the relationship between significance and storage requirements.
Table 3.3 Floating-Point Types
Type Significant digits Number of bytes
float 6 – 7 4
double 15 – 16 8
Floating-point variables are represented by a mantissa, which contains the value of the number, and an exponent, which contains the order of magnitude of the number.
Table 3.4 shows the number of bits allocated to the mantissa and the exponent for each floating-point type. The most significant bit of any float or double is always the sign bit. If it is 1, the number is considered negative; otherwise, it is considered a positive number.
Table 3.4 Lengths of Exponents and Mantissas
Type Exponent length Mantissa length
float 8 bits 23 bits
double 11 bits 52 bits
Because exponents are stored in an unsigned form, the exponent is biased by half its possible value. For type float, the bias is 127; for type double, it is 1023. You can compute the actual exponent value by subtracting the bias value from the exponent value.
The mantissa is stored as a binary fraction greater than or equal to 1 and less than 2. For types float and double, there is an implied leading 1 in the mantissa in the most-significant bit position, so the mantissas are actually 24 and 53 bits long, respectively, even though the most-significant bit is never stored in memory.
Instead of the storage method just described, the floating-point package can store binary floating-point numbers as denormalized numbers. “Denormalized numbers” are nonzero floating-point numbers with reserved exponent values in which the most-significant bit of the mantissa is 0. By using the denormalized format, the range of a floating-point number can be extended at the cost of precision. You cannot control whether a floating-point number is represented in normalized or denormalized form; the floating-point package determines the representation. The floating-point package never uses a denormalized form unless the exponent becomes less than the minimum that can be represented in a normalized form.
Table 3.5 shows the minimum and maximum values you can store in variables of each floating-point type. The values listed in this table apply only to normalized floating-point numbers; denormalized floating-point numbers have a smaller minimum value. Note that numbers retained in 80x87 registers are always represented in 80-bit normalized form; numbers can only be represented in denormalized form when stored in 32-bit or 64-bit floating-point variables (variables of type float and type long).
Table 3.5 Range of Floating-Point Types
Type Minimum value Maximum value
float 1.175494351 E – 38 3.402823466 E + 38
double 2.2250738585072014 E – 308 1.7976931348623158 E + 308
If precision is less of a concern than storage, consider using type float for floating-point variables. Conversely, if precision is the most important criterion, use type double.
Floating-point variables can be promoted to a type of greater significance (from type float to type double). Promotion often occurs when you perform arithmetic on floating-point variables. This arithmetic is always done in as high a degree of precision as the variable with the highest degree of precision. For example, consider the following type declarations:
float f_short;
double f_long;
long double f_longer;
f_short = f_short * f_long;
In the preceding example, the variable f_short is promoted to type double and multiplied by f_long; then the result is rounded to type float before being assigned to f_short.
In the following example (which uses the declarations from the preceding example), the arithmetic is done in float (32-bit) precision on the variables; the result is then promoted to type double:
f_longer = f_short * f_short;
*** END CLIP ***
Got that?
Think, mantissa times 2 to the power of the exponent. n = m * (2^exponent);
The mantissa is always stored as a number between (in binary) 1.0(0 forever) and 10.0(0 forever). So ''1.'' can be assumed and only the part to the right of the ''.'' is stored.
The exponent is unsigned, but represents -127 to 127.
Now the problem is this can''t be what Calculator''s doing. A double''s maximum is 2^52. Calculator lets you do 2^144269 (yes, that took me awhile to do by hand ).
Mike Roberts
aka milo
mlbobs@telocity.com
Couple of long clips and a few comments below for those interested.
From the Calculator''s Help. (you did read it didn''t you )
*** START CLIP ***
Understanding extended precision
Extended Precision, a feature of Calculator, implies that all operations are accurate to at least 32 digits. Calculator also stores rational numbers as fractions to retain accuracy. For example, 1/3 is stored as 1/3, rather than .333. However, errors accumulate during repeated operations on irrational numbers. For example, Calculator will truncate pi to 32 digits, so repeated operations on pi will lose accuracy as the number of operations increases. >>
*** END CLIP ***
So it is only guranteed accurate to 32 digits.
I would of guessed the actual format is something like a float or double in C++. Here is some major clippage from the Visual C++ 6.0 Help (MSDN actually).
*** START CLIP ***
(i''ve tried to make the tables neat)
Type float
Floating-point numbers use the IEEE (Institute of Electrical and Electronics Engineers) format. Single-precision values with float type have 4 bytes, consisting of a sign bit, an 8-bit excess-127 binary exponent, and a 23-bit mantissa. The mantissa represents a number between 1.0 and 2.0. Since the high-order bit of the mantissa is always 1, it is not stored in the number. This representation gives a range of approximately 3.4E–38 to 3.4E+38 for type float.
You can declare variables as float or double, depending on the needs of your application. The principal differences between the two types are the significance they can represent, the storage they require, and their range. Table 3.3 shows the relationship between significance and storage requirements.
Table 3.3 Floating-Point Types
Type Significant digits Number of bytes
float 6 – 7 4
double 15 – 16 8
Floating-point variables are represented by a mantissa, which contains the value of the number, and an exponent, which contains the order of magnitude of the number.
Table 3.4 shows the number of bits allocated to the mantissa and the exponent for each floating-point type. The most significant bit of any float or double is always the sign bit. If it is 1, the number is considered negative; otherwise, it is considered a positive number.
Table 3.4 Lengths of Exponents and Mantissas
Type Exponent length Mantissa length
float 8 bits 23 bits
double 11 bits 52 bits
Because exponents are stored in an unsigned form, the exponent is biased by half its possible value. For type float, the bias is 127; for type double, it is 1023. You can compute the actual exponent value by subtracting the bias value from the exponent value.
The mantissa is stored as a binary fraction greater than or equal to 1 and less than 2. For types float and double, there is an implied leading 1 in the mantissa in the most-significant bit position, so the mantissas are actually 24 and 53 bits long, respectively, even though the most-significant bit is never stored in memory.
Instead of the storage method just described, the floating-point package can store binary floating-point numbers as denormalized numbers. “Denormalized numbers” are nonzero floating-point numbers with reserved exponent values in which the most-significant bit of the mantissa is 0. By using the denormalized format, the range of a floating-point number can be extended at the cost of precision. You cannot control whether a floating-point number is represented in normalized or denormalized form; the floating-point package determines the representation. The floating-point package never uses a denormalized form unless the exponent becomes less than the minimum that can be represented in a normalized form.
Table 3.5 shows the minimum and maximum values you can store in variables of each floating-point type. The values listed in this table apply only to normalized floating-point numbers; denormalized floating-point numbers have a smaller minimum value. Note that numbers retained in 80x87 registers are always represented in 80-bit normalized form; numbers can only be represented in denormalized form when stored in 32-bit or 64-bit floating-point variables (variables of type float and type long).
Table 3.5 Range of Floating-Point Types
Type Minimum value Maximum value
float 1.175494351 E – 38 3.402823466 E + 38
double 2.2250738585072014 E – 308 1.7976931348623158 E + 308
If precision is less of a concern than storage, consider using type float for floating-point variables. Conversely, if precision is the most important criterion, use type double.
Floating-point variables can be promoted to a type of greater significance (from type float to type double). Promotion often occurs when you perform arithmetic on floating-point variables. This arithmetic is always done in as high a degree of precision as the variable with the highest degree of precision. For example, consider the following type declarations:
float f_short;
double f_long;
long double f_longer;
f_short = f_short * f_long;
In the preceding example, the variable f_short is promoted to type double and multiplied by f_long; then the result is rounded to type float before being assigned to f_short.
In the following example (which uses the declarations from the preceding example), the arithmetic is done in float (32-bit) precision on the variables; the result is then promoted to type double:
f_longer = f_short * f_short;
*** END CLIP ***
Got that?
Think, mantissa times 2 to the power of the exponent. n = m * (2^exponent);
The mantissa is always stored as a number between (in binary) 1.0(0 forever) and 10.0(0 forever). So ''1.'' can be assumed and only the part to the right of the ''.'' is stored.
The exponent is unsigned, but represents -127 to 127.
Now the problem is this can''t be what Calculator''s doing. A double''s maximum is 2^52. Calculator lets you do 2^144269 (yes, that took me awhile to do by hand ).
Mike Roberts
aka milo
mlbobs@telocity.com
I have done computations with reverse polish notation, and yes it is pretty neat.
Anyway, if you want super high precision (more than built in datatypes can handle) of your computations you'll have to make your own datatypes and math operations. I suggest you do it with the base 256 (just as normal decimal numbers has base 10) that way each digit fits in a byte.
235 1 234256 = 235*2562 + 1*2561 + 234*2560 = 1540145010
An example math operation would be addition, which is done the same way as with base 10 (and base 2 for that matter ).
235 1 234256 + 128 0 63256 = 1 107 2 41256
You could for example make a datatype which support numbers up to 25620 = 2160 = 1.46*1048, with the following structure:
struct SUPERLARGEINT
{
unsigned char Digits[20];
};
Good luck!
WitchLord
Edited by - WitchLord on 4/23/00 12:30:46 PM
Anyway, if you want super high precision (more than built in datatypes can handle) of your computations you'll have to make your own datatypes and math operations. I suggest you do it with the base 256 (just as normal decimal numbers has base 10) that way each digit fits in a byte.
235 1 234256 = 235*2562 + 1*2561 + 234*2560 = 1540145010
An example math operation would be addition, which is done the same way as with base 10 (and base 2 for that matter ).
235 1 234256 + 128 0 63256 = 1 107 2 41256
1 1 235 1 234+ 128 0 63-----------1 107 2 41
You could for example make a datatype which support numbers up to 25620 = 2160 = 1.46*1048, with the following structure:
struct SUPERLARGEINT
{
unsigned char Digits[20];
};
Good luck!
WitchLord
Edited by - WitchLord on 4/23/00 12:30:46 PM
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game
I know the calculator won't let you input a number greater than 2^144269, but it sure can handle numbers greater than that. The largest I can get is 2^553809.663153679564917404940549817. Pretty amazing, huh? That's actually 40000!. But since that's really just one calculation that you type in, isn't the answer still 32 digits accurate? So that means every number that it uses to calculate it must be accurate to many more digits than 32, or else the final answer will be so skewed that it isn't even correct. So the calculator really can handle really large numbers, and with very precise accuracy. But the real question is how it does it. So how?
ColdfireV
Don't you just hate it when someone replies just as you're writing? Thanks for the reply WitchLord. I guess the calculator does some sort of implementation of a structure like you described.
Edited by - ColdfireV on 4/23/00 12:33:30 PM
ColdfireV
Don't you just hate it when someone replies just as you're writing? Thanks for the reply WitchLord. I guess the calculator does some sort of implementation of a structure like you described.
Edited by - ColdfireV on 4/23/00 12:33:30 PM
[email=jperegrine@customcall.com]ColdfireV[/email]
Look at the thread "Help with HUGE numbers!?!" (last post 16 April).
Visit our homepage: www.rarebyte.de.st
GA
Visit our homepage: www.rarebyte.de.st
GA
Visit our homepage: www.rarebyte.de.stGA
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement