Looking for math library
Edgar Reynaldo

I'm looking for a decent math library. It has to satisfy the following conditions :

1) When scanned, "#.#" has to equal #.# - ie... "5.1" has to equal 5.1 when scanned from a string. Because currently if I use sscanf on "5.1" to get a double and then printf the double back out with high precision, it is 5.0999999999999996 instead of 5.1, and this occurs far too often with other numbers as well, even if it is only off by 4e-16 or so. I want to be able to move from string to double and back without losing any precision.

2) It should support at least as many math functions as the C standard library.

3) C or C++ only.

4) Non GPL if possible, but maybe you can convince me otherwise if
a) My code doesn't have to be GPL too.
b) I'm not forced to release all of my source code, even if I might anyway.

5) Optional - extra features?

I looked at The wikipedia list article of numerical libraries, but about the only thing that looked good at first glance was the GNU MultiPrecision Library. The GNU Scientific Library doesn't seem to offer precision greater than doubles do, only a truckload of math functions.

The problem with GMP is that it uses the LGPL, and I still haven't wrapped my head around what you can and can't do with the (L)GPL. I wish there was a (L)GPL for dummies guide around somewhere. :P

So, any recommendations / experience to share with me on this matter?

SiegeLord

I want to be able to move from string to double and back without losing any precision.

This is impossible. You need to have decimal fraction storage to do that, and double does not provide that.

I only know of GMP and GSL too, but generally I've never needed the additional precision of the first.

Matthew Leverton

You won't have a problem with LGPL libraries corrupting your source code as long as you dynamically link against them.

Arthur Kalliokoski

Because currently if I use sscanf on "5.1" to get a double and then printf the double back out with high precision, it is 5.0999999999999996 instead of 5.1,

#include <stdio.h>

double f;
int i;

int main(void)
{
  for(i=0;i<100;i++)
  {
    printf("%0.1lf %lf\n",f,f);  //print the single decimal place version followed by the ordinary version.
    f += 0.11111;
  }
  return 0;
}

decepto

I love this library, even when I'm not programming OpenGL. It's just great all around.

Edgar Reynaldo
SiegeLord said:

This is impossible. You need to have decimal fraction storage to do that, and double does not provide that.

I know double doesn't do that, and that was kind of the point.

You won't have a problem with LGPL libraries corrupting your source code as long as you dynamically link against them.

Dynamic linking is fine with me. Am I supposed to mention the library and provide a copy of the GPL and LGPL along with it? Can I just provide a link to the GPL, LGPL, and the url of the library used?

@Arthur Kalliokoski
I don't really know what you are trying to say with that code. Using a precision specifier with printf only allows you to specify the number of digits after the decimal point, not the actual number of significant digits. Ie 12.3 has 3 significant digits, not 1. It also does rounding, which I want to minimize as much as possible.

decepto said:

I love this library [glm.g-truc.net], even when I'm not programming OpenGL. It's just great all around.

It looks decent to start off, but there's no guarantee of precision with their two high precision data types :

typedef highp_float_t highp_float

High precision floating-point numbers.

There is no guarantee on the actual precision. From GLSL 1.30.8 specification

Definition at line 54 of file type_float.hpp.
typedef detail::highp_int_t highp_int

High precision signed integer.

There is no guarantee on the actual precision. From GLSL 1.30.8 specification.

Definition at line 62 of file type_int.hpp.

What I want most is to be able to have a number string convert to an exactly corresponding decimal data type and back again. I can limit the precision later if necessary.

The decNumber library is looking good too, except for the GPL bit. If I use a GPL library in my program, is my program then automatically bound by the GPL as well?

Arthur Kalliokoski

Using a precision specifier with printf only allows you to specify the number of digits after the decimal point, not the actual number of significant digits. Ie 12.3 has 3 significant digits, not 1. It also does rounding, which I want to minimize as much as possible.

You want to truncate digits? Why? If you want to eliminate rounding, multiply by the power of 10 you want to have the precision up to, floor() it, then divide again.
Or you could simply sprintf this number to a buffer, use strchr() to find the decimal point, use the index to the sought number for strcpy, etc. Sure, it'd be slower than pure math operations, but a library would slow things down as well.

tobing

If I use a GPL library in my program, is my program then automatically bound by the GPL as well?

Yes, you have to publish your source code as well under GPL. GPL is infectious.

When I found this: http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic I was surprised how many such libraries there are... I have no experiences with any of them, however.

Arthur Kalliokoski

I have a 32 bit assembler arbitrary precision library you can have if you want, but I haven't been motivated enough to finish the 64 bit version. To convert to assembly code for Windows, you'd have to add an underscore prefix to the global namespaces. I never did quite finish the transcendental functions either, but it does the fourbanger calculator stuff just fine, as well as print to ascii buffers and scan from ascii buffers.

james_lohr

You need to tell us what you want this for, because most likely you don't actually know what you really want; it is very unlikely that you need a fully blown Decimal library for whatever it is you are doing. Chances are that all you really need is to write your own double.ToString() method.

Edgar Reynaldo

You want to truncate digits? Why? If you want to eliminate rounding, multiply by the power of 10 you want to have the precision up to, floor() it, then divide again.
Or you could simply sprintf this number to a buffer, use strchr() to find the decimal point, use the index to the sought number for strcpy, etc. Sure, it'd be slower than pure math operations, but a library would slow things down as well.

No, I said I want to minimize rounding - ie maintain precision up to an arbitrary point, maybe around 30 significant digits or so. Multiplying and dividing by 10 won't help fix the failure in precision of statements like 0.1 or 1/10.

Also, super speed is not essential in this application. It won't be computationally expensive over long periods of time.

Tobing said:

Yes, you have to publish your source code as well under GPL. GPL is infectious.

<runs for antibiotics>

I have a 32 bit assembler arbitrary precision library you can have if you want, but I haven't been motivated enough to finish the 64 bit version. To convert to assembly code for Windows, you'd have to add an underscore prefix to the global namespaces. I never did quite finish the transcendental functions either, but it does the fourbanger calculator stuff just fine, as well as print to ascii buffers and scan from ascii buffers.

I appreciate the offer, but I'm going to need trig functions.

You need to tell us what you want this for, because most likely you don't actually know what you really want; it is very unlikely that you need a fully blown Decimal library for whatever it is you are doing. Chances are that all you really need is to write your own double.ToString() method.

I've already written a FormatDouble function, and it works fine. It retains the maximum amount of precision available from a double and strips leading and trailing zeros and optimizes the exponent for string length consideration.

What I'm using it for is a console/plotter program that lets you enter equations as strings and then evaluate / simplify / derive / integrate? / plot them.

The LUA interpreter has better precision than a C++ double - it doesn't have any problem with 5.1 or 0.1, or most other common (relatively small) numbers and has precision of somewhere around 14 digits.

BTW, keep comments like 'I don't actually know what I really want' to yourself. I've already stated several times that I want more precision than doubles afford, and I want perfect string to decimal data type and back to string conversions.

Audric

The restrictions of LGPL are super-light. If you don't need modify the "official" DLL, you only need to provide a readme like this one:

doc/README-SDL.txt said:

The following file:

SDL.dll

is the runtime environment for the SDL library.

The Simple DirectMedia Layer (SDL for short) is a cross-platfrom library
designed to make it easy to write multi-media software, such as games and
emulators.

The Simple DirectMedia Layer library source code is available from:
http://www.libsdl.org/

This library is distributed under the terms of the GNU LGPL license:
http://www.gnu.org/copyleft/lesser.html

A little more complex example where I had to compile the DLL myself: since I didn't have to modifiy the sources, I simply point to the specific versions used :

doc/README-SDL_image.txt said:

The following file

SDL_image.dll

is the runtime environment for the library SDL_image 1.2.10 by Sam Lantiga and Mattias Engdegård.

This library is distributed under the terms of the GNU LGPL license:
http://www.gnu.org/copyleft/lesser.html

The source is available from the libraries page at the SDL website:
http://www.libsdl.org/

=========================

Compiled by yrizoud on 16/06/2010 with static builds of :
libjpeg (JPEG library http://www.ijg.org/ release 6b of 27-Mar-1998 : jpegsr6.zip)
libtiff (TIFF library ftp://ftp.sgi.com/graphics/tiff/ : tiff-v3.4-tar.gz)
And dynamic version of :
libpng (http://www.libpng.org/pub/png/libpng.html) v1.4.2 --> libpng14-14.dll requirement

Edgar Reynaldo

@Audric
That sounds reasonable enough.

The MAPM library is looking pretty good so far - it has most of the standard C math functions implemented and supports arbitrary precision math as well as conversion to and from c strings.

james_lohr

It makes it all too apparent what a dated language C++ is; Java has had BigDecimal for over a decade, and "decimal" is a basic type in C#.

Kitty Cat

It makes it all too apparent what a dated language C++ is; Java has had BigDecimal for over a decade, and "decimal" is a basic type in C#.

Except it isn't a basic type. It may be built-in to the language, but the CPU/FPU doesn't handle it directly. Software has to break it down, do the work, then reconstruct it.

C/C++'s basic types are what the processor deals with. You don't even get float and double if your target machine doesn't have an FPU (unless your compiler offers FPU emulation, but that's not required as part of the language).

At most, it could be part of libc/libstdc++, but there are already libraries which implement it just fine.

Arthur Kalliokoski

IIRC, the lcc-win32 compiler has arbitrary precision arithmetic, but lcc-win32 is slow and you can't use it for commercial programs.

orz

1) When scanned, "#.#" has to equal #.# - ie... "5.1" has to equal 5.1 when scanned from a string. Because currently if I use sscanf on "5.1" to get a double and then printf the double back out with high precision, it is 5.0999999999999996 instead of 5.1, and this occurs far too often with other numbers as well, even if it is only off by 4e-16 or so. I want to be able to move from string to double and back without losing any precision.

I don't think you should ask for something like that without specifying what your precision requirements are.

If you only care about destringifaction+stringification not producing the original value, simply limiting every decimal stringification to 14 digits meets your requirements well over a fairly wide range of numbers, though that's actually a decrease in precision.

On the other hand if you need purely decimal math, that's a very different thing (though it would solve the above problem as long as all stringifications were to decimal). Likewise if you need infinite precision.

Evert

Java has had BigDecimal for over a decade, and "decimal" is a basic type in C#.

Since computers use binary rather than decimal, I would consider that a rather useless feature.
I mean, sure, you can't express decimal farctions exactly in a binary representation, but they're both equally arbitrary anyway. You can't express a fraction of a third exactly in either, for instance.

Kitty Cat
orz said:

If you only care about destringifaction+stringification not producing the original value, simply limiting every decimal stringification to 14 digits meets your requirements well over a fairly wide range of numbers, though that's actually a decrease in precision.

Or you can use %a (C99), which uses a hexadecimal notation for floating-point values. The default precision allows you to distinguish between two double values.

a, A   (C99; not in SUSv2) For a conversion, the double argument  is  converted  to
       hexadecimal notation (using the letters abcdef) in the style [-]0xh.hhhhp±d;
       for A conversion the prefix 0X, the letters ABCDEF, and the exponent separa‐
       tor P is used.  There is one hexadecimal digit before the decimal point, and
       the number of digits after it is equal to the precision.  The default preci‐
       sion suffices for an exact representation of the value if an exact represen‐
       tation in base 2 exists and otherwise is sufficiently large  to  distinguish
       values  of  type  double.  The digit before the decimal point is unspecified
       for nonnormalized numbers, and nonzero but otherwise unspecified for normal‐
       ized numbers.

William Labbett
Evert said:

I mean, sure, you can't express decimal farctions exactly in a binary representation, but they're both equally arbitrary anyway. You can't express a fraction of a third exactly in either, for instan

...let alone irrational numbers.

What about the gnu big number library ? Not sure if that would help.

Audric

The decimal type in C# is not for mathematicians, but accountants.

Arthur Kalliokoski
Audric said:

The decimal type in C# is not for mathematicians, but accountants.

Isn't the '#.#' specifier from COBOL? It's meant for accountants and $PHB's.

Edgar Reynaldo
orz said:

I don't think you should ask for something like that without specifying what your precision requirements are.

My precision requirements are that string numbers have an exact representation when converted to data. With my current implementation using doubles, my command line calculator / function parser is too stupid to return 51 for 5.1/0.1. That's just not acceptable to me, nor should it be acceptable to anyone using a calculator program.

Kitty Cat said:

Or you can use %a (C99), which uses a hexadecimal notation for floating-point values. The default precision allows you to distinguish between two double values.

Kitty Cat said:

The default precision suffices for an exact representation of the value if an exact representation in base 2 exists and otherwise is sufficiently large to distinguish values of type double.

This is the basis of the problem - most base 2 floating point representations are just incapable of representing decimals correctly. If they used base 2 to represent the numerals and used a separate number to represent the decimal point, then there shouldn't ever be a problem with it, but you can't represent every number with powers of 1/2.

What about the gnu big number library ? Not sure if that would help.

That's the same thing as the GNU Multi Precision library. I'm looking into it.

verthex

Theres LIDIA but I'm not sure what it could do for you.

Arthur Kalliokoski

With my current implementation using doubles, my command line calculator / function parser is too stupid to return 51 for 5.1/0.1.

#SelectExpand
1#include <stdio.h> 2#include <stdlib.h> 3#include <errno.h> 4 5int main(int argc, char **argv) 6{ 7 double parm1; 8 double parm2; 9 double result; 10 int intresult; 11 int operator; 12 char *end1; 13 14 if(argc != 2) 15 { 16 fprintf(stderr,"I want one string in quotes to parse for four banger math, e.g. \"5/4\"\n"); 17 return 0; 18 } 19 20 errno = 0; 21 parm1=strtod(argv[1],&end1); 22 if(errno == ERANGE) 23 { 24 fprintf(stderr,"First number out of range\n"); 25 return 1; 26 } 27 28 operator = (char)*end1; 29 30 end1++; 31 32 parm2=strtod(end1,0); 33 34 switch(operator) 35 { 36 case '+': 37 result = parm1 + parm2; 38 break; 39 case '-': 40 result = parm1 - parm2; 41 break; 42 case '*': 43 result = parm1 * parm2; 44 break; 45 case '/': 46 result = parm1 / parm2; 47 break; 48 default: 49 fprintf(stderr,"Operator '%c' isn't allowed\n",operator); 50 return 1; 51 } 52 53 intresult = result; 54 if(intresult == result) 55 printf("answer is %d\n",intresult); 56 else 57 printf("answer is %lg\n",result); 58 59 return 0; 60}

[EDIT]

Forgot the range check on second number, but you know what I mean...

[EDIT2]

The arbitrary precision lib I mentioned earlier does have transcendental functions, but some of them could be optimized with precalculated numbers in a file for identities, which I haven't bothered with.

I tried it just to see how fast it was on this 3.1Ghz Athlon II, but somehow argc & argv were getting corrupted. After hours of fiddling with gdb, valgrind and Electric Fence, I tried the Watcom compiler, which worked fine (although Watcom crashes on an fflush() :P).

Printing gives out results like:

count = 7021

Input number    0.7021
Sin    0.6458224341509764981664646025062778090792175100125560862802365350598448
Cos    0.7634876446592358739582226598267228849622487768704818372243868793930424
Tan    0.8458845911504221153467969183513439373684976836083291157721866966077248

count = 7022

Input number    0.7022
Sin    0.6458987796862030057491918266634106923511167321066618731945697836968761
Cos    0.7634230585984901932657298394753035699212712280249010525166211455076285
Tan    0.846056157737701829266851733611519926546263348925174306300998247937501

count = 7023

Input number    0.7023
Sin    0.6459751187624417218523788222528204136464410918821905557397273206694932
Cos    0.7633584649035139329501939060000511971689937336425396753570132724535036
Tan    0.8462277533584315588906546332567283389122943855797825858950950746135725

and here's how long it takes to print out 10000 loops with 80 bytes in the integral part and 80 bytes in the fractional part. The first one is redirecting to results.txt, where the output above was copied from.

pepsi@fractal_comet:/home/prog/bignums 02:49 AM $ time t > results.txt

real    0m59.132s
user    0m59.021s
sys     0m0.087s
pepsi@fractal_comet:/home/prog/bignums 02:50 AM $ time t noprint

real    0m0.038s
user    0m0.038s
sys     0m0.000s
pepsi@fractal_comet:/home/prog/bignums 02:50 AM $ 

The second timing result is how long it takes to calculate the trig funcs (1/30 of a second for all 30000 results) but not printing to decimal (quite a chore in itself)

[EDIT5]

I forgot to show the input number for the trig stuff... edited all the above

[EDIT6]

Recompiling with 800 bytes of integral and decimal bytes with 700 decimal positions printed gives this for 100 loops

pepsi@fractal_comet:/home/prog/bignums 03:02 AM $ time t > results.txt

real    4m9.194s
user    4m8.927s
sys     0m0.093s
pepsi@fractal_comet:/home/prog/bignums 03:07 AM $ time t noprint

real    0m0.004s
user    0m0.003s
sys     0m0.000s

noprint is faster than before because only 100 loops

count = 42

Input number    0.42
Sin    0.4077604530595701859727871580863423156477998312272199837618432020183270288765336837439844031983341253779690576147116094979039277815379680051349489526859390640113444468728511707118838605394853620887365370981415293797665495368793143468270256405581832984876247762177846669463896709533912328054270139386495849713716053377167824292341132590924517670116080193774565000394404325176018879137001116501917905458262931179583116640073280342696907129516730267817169709076756630570369478068356496088806733562791025935518005717823975399647433911242565646284290408108965129580005045630325009645600351052252234931946795935673759622200090939484176528145403518844626429027118291618481207436517990068199382319726055853613
Cos    0.9130889403123082724360887896656672808656036779177695185367711006995955759007027812268532869219485750392032411157021985701743449718712839893630769060956987500869050561130530606277722475164033362715938822340958362676305487363307447311046606036732548594394880660779345469357363927362599236287787967113779712125417724313266162079002839798171344659068700365238628373106988573793108841436286988550471435158583090282785551299521559463196485941733155093326870424140702825354668014736012094116310173282063294354797176618106265223818473429154560119875265514193935088602078450686698516654784487568476528092182943197051363283336770971514484898843637969744795863457522041097293912185666895010296292417843629169566
Tan    0.4465725462845951080354340492493297863664702530228539431793643752790652121798457119308281093711337117351824302405127265043941078743201413802742986904431097907418452657673429572010439544368058258668460621337750507856743137674138128805462521543172690127434221187279537588377878373065777689804867923360071570888272946017486343012618629153112816524990960304473577139058272000642627832629543035542998512407586811092722803660439984439880202739952675782181893386116210218071303871409986764914583800844104115292506997715868582578179441467373632677384179542325076687281260631102061490708090583107700757824466976889133117431057537299832543055583282997302563566765119476476011271217072270990986942660758601073145

james_lohr

but you can't represent every number with powers of 1/2.

Nor can you represent every number with powers of 10: 10 is a totally arbitrary base.

Your posts still strongly suggest that you don't really know what you want because you don't seem to be able to grasp what is going on.

If you want your calculator to round to decimal values, then round to decimal values. Most calculators already do this: if you enter 1/3, then multiply the answer by 3, you will get 1 again, despite the fact that 1/3 can be expressed in neither decimal nor binary.

I still don't see strong enough grounds for using a decimal base for what you are doing. In fact any hand calculator could quite easily be running on base 2 and you'd never even know.

The only real grounds for a decimal base is working financial purposes. It is certainly not appropriate for your purposes, and if you intend to do any sort of numerical integration or any real number crunching for that matter, you will be slowing down your application 10-50 fold by using a decimal base.

weapon_S

Who says Edgar isn't doing a financial program? :P

Evert

With my current implementation using doubles, my command line calculator / function parser is too stupid to return 51 for 5.1/0.1. That's just not acceptable to me, nor should it be acceptable to anyone using a calculator program.

Utter nonsense.
When using any kind of tool, whether software or not, you have to understand its limitations. One of the limitations of computers is that floating point arithmetic has finite accuracy. There is ultimately no way around it and it's a bad idea to try to fake it in specific circumstances. It'll break down in other points.
Now, it may be appropriate to define operations on rational numbers (which is just a pair of integers), of which a decimal representation is just a subset. If that's what you want, then that's what you should implement (which is not difficult and is somewhat fun to do; it's not generally useful though).

Arthur Kalliokoski
orz

My precision requirements are that string numbers have an exact representation when converted to data. With my current implementation using doubles, my command line calculator / function parser is too stupid to return 51 for 5.1/0.1. That's just not acceptable to me, nor should it be acceptable to anyone using a calculator program.

As James Lohr said, you're simply not understanding what you see in calculators. Some of them are in base 2, some are in decimal, and you generally don't notice the difference. Different ones use different precision, but they generally display accurate integer answers to operations with divisors that don't fit in to their base evenly by the simple trick of displaying fewer digits than they calculate internally. If you divide 1 by 3 and then multiply it by 3 it displays the result as 1.0 not because it internally calculates the result as 1.0 (most calculators don't) but because it displays fewer digits then it tracks internally. Which is sort of like the opposite of the property you asked for - the destringification of the stringification is not equal to the original number, and that loss of precision is what gives them the property you like.

Arthur Kalliokoski: I wouldn't recommend actually using the BCD opcodes. It's comparable in efficiency to emulate that using normal integers (the BCD opcodes are slow on many x86s), and compiler support / etc is much better for non-BCD stuff.

Arthur Kalliokoski
orz said:

Arthur Kalliokoski: I wouldn't recommend actually using the BCD opcodes. It's comparable in efficiency to emulate that using normal integers (the BCD opcodes are slow on many x86s), and compiler support / etc is much better for non-BCD stuff.

I'd rather doubt this would be a problem for a calculator app.

Edgar Reynaldo
verthex said:

Theres LIDIA [www.cdc.informatik.tu-darmstadt.de] but I'm not sure what it could do for you.

The Introduction to LIDIA seems to indicate that it is highly specialized in things I don't have a use for, and it makes no mention of trig / power / logarithm / other standard C/C++ functions. Thanks anyway.

Arthur Kalliokoski said:

...code example...

I don't see why strtod would give different results than sscanf would. As written, calling the program with 5.1/0.1 as the argument produces 51 as the answer. The problem is, I can't rely on %lg to correctly round the number in all cases. If I change it to use %.30lg I get 50.999999999999993 as the answer. What if the answer actually was 50.999999999999993 and I used %lg and got 51 as the output instead?

I just can't rely on doubles to do what I want them to do.

The arbitrary precision lib I mentioned earlier does have transcendental functions, but some of them could be optimized with precalculated numbers in a file for identities, which I haven't bothered with.

How does your library compare to MAPM?

Nor can you represent every number with powers of 10: 10 is a totally arbitrary base.

You can represent more with powers of 10 than you can with powers of 1/2. :P If doubles used positive powers of 2 and tracked the decimal point and exponent, we wouldn't be having this discussion. :P

James Lohr said:

Your posts still strongly suggest that you don't really know what you want because you don't seem to be able to grasp what is going on.

Figure it out dude, I want an exact representation (as much as possible) when converting from string to data and back. I've said this several times. Perhaps you have poor reading comprehension, I don't know. I know what is going on, I already stated that powers of 1/2 are insufficient for my needs for data representation. Since you're so smart, why don't you enlighten me and tell me 'what is going on'.

James Lohr said:

If you want your calculator to round to decimal values, then round to decimal values.

The problem is, how much precision should I choose to lose? If I decide to round everything to 10ths then I lose a lot of precision in my operations and the user may want to specify precision in the 1000ths. The MAPM library specifically allows me to choose how many significant digits their numbers should use, which makes it a lot easier for me.

James Lohr said:

I still don't see strong enough grounds for using a decimal base for what you are doing. In fact any hand calculator could quite easily be running on base 2 and you'd never even know.

The base itself doesn't bother me, what bothers me is using negative powers of that base to represent a number, which is stupid because it usually can't be done precisely (but negative powers of base 10 are more precise than negative powers of base 2).

weapon_S said:

Who says Edgar isn't doing a financial program?

Well, actually I'm not, but thanks for the support.

Evert said:

Utter nonsense.
When using any kind of tool, whether software or not, you have to understand its limitations. One of the limitations of computers is that floating point arithmetic has finite accuracy. There is ultimately no way around it and it's a bad idea to try to fake it in specific circumstances. It'll break down in other points.

No, what is nonsense is to return an inexact number for a mathematical operation that should have an exact value. It's the implementation of floating point arithmetic that sucks here, as you can represent any rational number with any positive base using positive powers if you track the decimal point and exponent as well. You shouldn't have to round the result of 5.1/0.1 to get the exact answer that obviously exists already. eg...

5.1 e0 = 51 e-1
/         / 
0.1 e0 =  1 e-1
----------------
         51 e0

When you represent the number in positive powers of any positive base greater than 1, there is no precision lost, ever (not accounting for irrational numbers here).

orz said:

Different ones use different precision, but they generally display accurate integer answers to operations with divisors that don't fit in to their base evenly by the simple trick of displaying fewer digits than they calculate internally.

But the problem is deciding how many digits to round the answer to. 2? 10? When you have an exact answer, you don't need to round anything.

orz said:

Which is sort of like the opposite of the property you asked for - the destringification of the stringification is not equal to the original number, and that loss of precision is what gives them the property you like.

I think you meant that the other way round, but I don't want 0.1 represented as 0.099999999whatever, that's just not acceptable.

In any case, I'm leaning more and more towards using the MAPM library - it has a really nice C++ class called MAPM that wraps all the C code into nice operators and you can set a global precision level for all the operations. I'll have to give it a test run here over the next few days and report back. And its example calculator program knows what 5.1/0.1 is. ;)

Arthur Kalliokoski

How does your library compare to MAPM?

I don't know, it all started when all I had was an assembler and an 8086 computer with no math chip. I'd guess that MAPM uses pure C, so I'd have an advantage for smaller sizes (a few kb per "number") because I can directly use the flags etc. in assembler, but most of the C implementations use FFT's to optimize multiplies etc., so they'd be faster then.

Quote:

You can represent more with powers of 10 than you can with powers of 1/2. :P

So switch to base 12 then. :D

Quote:

I don't want 0.1 represented as 0.099999999whatever, that's just not acceptable.

Try this on your hand held calculator:
1 / 3 = x
x * 3 = x (equal to 1 <-- or so it says)
Now subtract 1 and look at the inaccuracy it was hiding.

Edgar Reynaldo

Try this on your hand held calculator:

Both the Windows calculator and my CASIO fx-115ES give the answer of zero.

Arthur Kalliokoski

Both the Windows calculator and my CASIO fx-115ES give the answer of zero.

I'm pretty sure all the desktop calculator applets use arbitrary precision math now, but if a CASIO hides it I'm impressed! OTOH, I haven't had a good hand held calculator for many years. I use a cheap $1.00 calculator in the cab, I'm pretty sure it'd give 0.99999999 for 1/3 * 3.

Edgar Reynaldo

It's a CASIO, but it's rather complex. I just opened it up after it sitting there for a year or so. It looks like it can do simple equations, do calculations on regular and complex numbers, handle matrices and vectors and some other stuff. I used to have a really nice TI-80 something graphical calculator back in high school. That thing was great til it crapped out.

Evert

What if the answer actually was 50.999999999999993 and I used %lg and got 51 as the output instead?

Read up on finite machine precision and the limitations that imposes. Numbers for which the difference is smaller than the machine precision are effectively the same.

Quote:

You can represent more with powers of 10 than you can with powers of 1/2.

Bullshit. They're equally arbitrary.

Quote:

No, what is nonsense is to return an inexact number for a mathematical operation that should have an exact value.

The output is only as good as the input. Your input is not infinitely precisise, so neither is your output.
Again, understand the limitations of what you're working with.

Quote:

It's the implementation of floating point arithmetic that sucks here, as you can represent any rational number with any positive base using positive powers if you track the decimal point and exponent as well. You shouldn't have to round the result of 5.1/0.1 to get the exact answer that obviously exists already.

Neither of those numbers can be represented exactly using a finite number of powers of 2, so what the computer stores is not 5.1, but 5.1 +/- eps, where eps is ~1e-16 for double precision. It's not broken, you simply don't understand.
Now, again, you could implement a rational number class that allows you to store fractions exactly as a tuple of integers. That way you can work with fractions without rounding. Doesn't help you when using real numbers though.

Try this on your hand held calculator:
1 / 3 = x
x * 3 = x (equal to 1 <-- or so it says)
Now subtract 1 and look at the inaccuracy it was hiding.

Cube root of 8, divide by 2 minus 1 or something like that is also a well-known example that shows finite precision on a calculator.

james_lohr

(but negative powers of base 10 are more precise than negative powers of base 2)

facepalm

Edgar Reynaldo
Evert said:

Read up on finite machine precision and the limitations that imposes. Numbers for which the difference is smaller than the machine precision are effectively the same.

If the difference between them was smaller than the machine precision, then you wouldn't be able to tell them apart in the first place.

Evert said:

Edgar said:

You can represent more with powers of 10 than you can with powers of 1/2.

Bullshit. They're equally arbitrary.

The proof is simple - you can represent any power of 2 with powers of 10, but you cannot represent every power of 10 with powers of 2.

Evert said:

The output is only as good as the input. Your input is not infinitely precisise, so neither is your output.
Again, understand the limitations of what you're working with.

The input is perfectly precise, so I expect the output to be perfectly precise as well as long as it is not an irrational number. I understand the limitations of floats and doubles and that is the entire purpose of this thread - to find an implementation that doesn't suffer this problem.

Evert said:

Neither of those numbers can be represented exactly using a finite number of powers of 2, so what the computer stores is not 5.1, but 5.1 +/- eps, where eps is ~1e-16 for double precision. It's not broken, you simply don't understand.

I know they can't be represented exactly in powers of 1/2, that's the point! So yes, it is broken as far as I'm concerned, because it is perfectly reasonable to expect an exact answer when there is one! I understand that floats and doubles can't do this, so stop telling me I don't understand.

James Lohr said:

Edgar said:

(but negative powers of base 10 are more precise than negative powers of base 2)

facepalm

Can you represent 10e-1 in powers of 2? I don't think so. Can every power of 2 be represented in powers of 10 - yes! Can every power of 10 be represented in base 2 - no! Therefore powers of 10 can represent more numbers than powers of 2 can when using negative powers, hence base 10 is more precise when using negative powers to represent numbers.

Facepalm that, sophomore. :P

bamccaig

<<<

The proof is simple - you can represent any power of 2 with powers of 10, but you cannot represent every power of 10 with powers of 2.

I'm not really sure what you mean by powers of 10 vs. powers of 2... In any case, the inaccuracy of number storage basically come down to finite storage. Infinite numbers cannot be stored in finite space and very long numbers cannot feasibly be processed either. Your basic options are floating-point numbers, which can represent a larger range of numbers with less precision, and fixed-point numbers, which can represent a smaller range of numbers with greater precision (and perhaps slower, since there are no fixed-point processing units in CPUs that I'm aware of). According to Wikipedia, fixed-point data types are split into two categories: binary (base 2) and decimal (base 10). The binary ones can benefit from bitwise operations to increase performance, but suffer from worse accuracy as a result. The decimal ones would therefore be slower, but more accurate. It all depends on exactly what you're using the numbers for.

>>>Prepend

I think what you basically want is a fixed-point data type. :) Apparently GCC partially supports a draft for one in C.[1] Of course, I don't know if the appropriate facilities are implemented to serialize and deserialize it. If you have to convert to/from a floating-point number to serialize/deserialize then you'll lose the precision anyway. :P It certainly would be nice to have fixed-point data types in all programming language standard libraries. There are some applications (financial, in particular) that can benefit a lot from the accuracy, and in those applications speed is often less important than accuracy.

<<<Append

Personally, I find it annoying too to get incorrect results with floating-point numbers. Perhaps that is my obsessive/perfectionist nature. I never have really wrapped my head around how to handle floating-point numbers appropriately. Though since I predominantly write business applications the floating point numbers usually represent money, where accuracy usually does matter...

>>>

Evert

The proof is simple - you can represent any power of 2 with powers of 10, but you cannot represent every power of 10 with powers of 2.

And neither of them does a particularly good job with powers of 3 or powers of 7.
The reason that you can represent powers of 2 using a finite number of positions using base 10 and not the other way around is that 2 is prime and 10 is not (in fact, it's 2x5, which is why it can represent powers of 2 and powers of 5 neatly). If you pick a base with even more prime number factorisations, it could do even better (by that measure)!
That doesn't change the fact that both bases are equally valid choices and equally arbitrary.

Quote:

The input is perfectly precise,

No, it isn't. That's what you don't seem to get.

Quote:

I understand the limitations of floats and doubles and that is the entire purpose of this thread - to find an implementation that doesn't suffer this problem.

There isn't one, since whichever base you pick, there are rational numbers that cannot be expressed with a finite number of "decimals" (namely those that have a prime number in their factorisation that is not in your base).
Again, if you want to do operations on rational numbers without converting them to floats, write a class that handles rational numbers.

Quote:

I know they can't be represented exactly in powers of 1/2, that's the point! So yes, it is broken as far as I'm concerned, because it is perfectly reasonable to expect an exact answer when there is one! I understand that floats and doubles can't do this, so stop telling me I don't understand.

Ok, good.
You don't act as though you understand, but if you do, good.
Anyway, no, the input is not exact. Computers operate in binary. You cannot represent "5.1" exactly in binary, so the input is not exact. That's leaving completely aside that, depending on where you're coming from, "5.1" doesn't necessarily mean "51/10", but could mean "a number in the range [5.05, 5.15)".
If you want to represent "51/10" exactly, write a class that handles rational numbers. That way you can store the number exactly and calculate things without rounding errors.
Floating point numbers are not broken, they may simply not be what you're looking to use. In which case, you should be more clear about what it is that you want to do.

Quote:

Though since I predominantly write business applications the floating point numbers usually represent money, where accuracy usually does matter...

If you can't tolerate numerical noise, then you should probably use a fixed-point system.
By the way, the "issue" with floating point numbers is not an issue with accuracy, it's an issue with precision.

EDIT: just one extra remark, but first

Quote:

Therefore powers of 10 can represent more numbers than powers of 2 can when using negative powers, hence base 10 is more precise when using negative powers to represent numbers.

I'm not going to argue the point because I can't be bothered to check it, but I suspect this may not be true. Remember, afterall, that the number of even natural numbers is the same as the total (odd+even) natural numbers (which is not intuitively obvious at all). I think the same sort of proof can show that your statement above is untrue, but as I said, I can't be bothered to check that.

My extra remark is this: independent of which base you choose, you will never be able to represent numbers like sqrt(2), pi or log(3) exactly by a finite number of negative powers of your base. If you do want to represent those "properly", you can certainly do that, but it's a lot more complicated. Computer algebra systems (CASs) like Maple and Mathematica do that. The fact that you cannot represent them exactly as a simple number using a finite number of terms has nothing at all to do with limitations of floating point, or even integer arithmetic.
Again, you have to use the correct tool for the job and understand its limitations. If I want to keep sqrt(2) as sqrt(2), I'll use pen and paper (or a CAS). If I want its numerical value, I rather have it as 1.414... to whichever number of significant digits I'm working with. Which representation is more "correct" or convenient depends on what I'm going to use it for.

Edgar Reynaldo
Evert said:

And neither of them does a particularly good job with powers of 3 or powers of 7.

I can deal with that. What I can't deal with is not being able to represent powers of 10 exactly, since that is what the decimal system is based on.

Evert said:

If you pick a base with even more prime number factorisations, it could do even better (by that measure)!

That doesn't change the fact that both bases are equally valid choices and equally arbitrary.

You're contradicting yourself. First you say they're equally valid and then you admit that powers of 10 can represent more numbers than powers of 2. Are powers of 10 a better representation of numbers than powers of 2 or not? Well, yes they are.

Evert said:

Edgar said:

The input is perfectly precise,

No, it isn't. That's what you don't seem to get.

What is imprecise about 5.1? It is exactly 51 10ths. The fact that a double can't represent 51 10ths is what bothers me. I get it just fine, thanks.

Evert said:

There isn't one, since whichever base you pick, there are rational numbers that cannot be expressed with a finite number of "decimals" (namely those that have a prime number in their factorisation that is not in your base).
Again, if you want to do operations on rational numbers without converting them to floats, write a class that handles rational numbers.

If they were represented as sums of any base greater than 1 with powers greater than or equal to 0 with a decimal point and exponent tracked separately, then any rational number could be represented exactly by them. The entire problem stems from the fact that negative powers are used to represent numbers less than one.

Evert said:

Computers operate in binary. You cannot represent "5.1" exactly in binary, so the input is not exact.

Yes you can represent it in binary if you use positive powers of two and track the decimal point and exponent.

"5.1" = 0x33 decimal2 e-1

Evert said:

Floating point numbers are not broken, they may simply not be what you're looking to use. In which case, you should be more clear about what it is that you want to do.

Floating point numbers are broken if they can't represent a decimal string exactly. I've said numerous times that I expect a string to be represented exactly in data format and to get the same string out when converting back. Why do I have to keep saying this?

Edit for your edit

Evert said:

I'm not going to argue the point because I can't be bothered to check it, but I suspect this may not be true. Remember, afterall, that the number of even natural numbers is the same as the total (odd+even) natural numbers (which is not intuitively obvious at all). I think the same sort of proof can show that your statement above is untrue, but as I said, I can't be bothered to check that.

Not true.

x != x + n (for n != 0)

Evert said:

My extra remark is this: independent of which base you choose, you will never be able to represent numbers like sqrt(2), pi or log(3) exactly by a finite number of negative powers of your base.

I understand I can't exactly represent irrational numbers. I'm not trying to either.

Arthur Kalliokoski

If it is for financial stuff, just use ints (counting pennies), have a special atoi routine that sticks a decimal point in the right spot, and you'll only have to use doubles for stuff like compound interest (which is never exact anyway).

Matthew Leverton

I love nerd fights.

Floating point numbers are broken if they can't represent a decimal string exactly.

Perhaps they are broken for your particular application, but they make good sense in terms of speed and functionality trade off.

james_lohr

Can you represent 10e-1 in powers of 2? I don't think so. Can every power of 2 be represented in powers of 10 - yes! Can every power of 10 be represented in base 2 - no! Therefore powers of 10 can represent more numbers than powers of 2 can when using negative powers, hence base 10 is more precise when using negative powers to represent numbers.

Facepalm that, sophomore.

No.

Take n bits. How many unique real numbers can be represented in base 2? Easy: 2^n. How many unique real numbers can be represented in base 10? - Always fewer than 2^n, because you need at least 4 bits to represent a single digit.

So on a platform of bits (which happens to be what all ordinary computers use), base 2 has more precision. This is if you define precision to be: "how accurately can an arbitrary real number be represented".

Your definition of precision appears to be "how accurately can a base 10 number be represented", which makes little sense given your intended application.

Edgar Reynaldo

Take n bits. How many unique real numbers can be represented in base 2? Easy: 2^n. How many unique real numbers can be represented in base 10? - Always fewer than 2^n, because you need at least 4 bits to represent a single digit.

If all it takes is a little extra space to get accurate results, I'm fine with that.

James Lohr said:

So on a platform of bits (which happens to be what all ordinary computers use), base 2 has more precision. This is if you define precision to be: "how accurately can an arbitrary real number be represented".

Negative powers of 2 do not have more precision than negative powers of 10, otherwise they could represent more numbers than negative powers of 10 could, which they can't. Any real number that is rational can be represented in base 10. The same can't be said for base 2 unless you use positive powers to represent the number and track the exponent.

James Lohr said:

Your definition of precision appears to be "how accurately can a base 10 number be represented", which makes little sense given your intended application.

It makes perfect sense, given that my intended application is accurate calculation of expresssions where possible.

In any case, you've babbled on enough about how I don't really know what I want, about how I can't grasp what is going on, blah blah blah. If you don't have any suggestions about how to achieve what I have plainly asked for numerous times, then stop posting in this thread already.

Evert

You're contradicting yourself. First you say they're equally valid and then you admit that powers of 10 can represent more numbers than powers of 2.

That's not a contradiction.

Quote:

Are powers of 10 a better representation of numbers than powers of 2 or not? Well, yes they are.

No they're not.

Quote:

Floating point numbers are broken if they can't represent a decimal string exactly.

No they're not. They would be if they couldn't represent a binary string exactly, but they can. Computers use binary, not decimal.

Quote:

I've said numerous times that I expect a string to be represented exactly in data format and to get the same string out when converting back. Why do I have to keep saying this?

Because you keep not getting that you're spouting nonsense?

Quote:

Not true.
x != x + n (for n != 0)

What's not true? The number of even integers being the same as the total number of integers? Shows your ignorance if that's what you meant.
And yes, x = x+n can be true if x is infinite.

Quote:

I understand I can't exactly represent irrational numbers. I'm not trying to either.

No, but you're trying to do something analogous.

Audric

I think that the statement that put everybody off-track was move from string to double and back.
I'm pretty sure it was not intended with infinite number of decimal places that can be obtained during a computation (ex: 1/3), but rather for the numbers that are input by humans.
The answer is a decimal floating-point or a decimal fixed-point number representation, as already proposed : Not because it would be more exact than a base-2 system, but because the rounding rules are on the same digits that a human would apply, and thus they appear more 'natural'.

Everybody asked "what's it for" because the choice between the two (fixed or floating) depends on what kind of actual numbers you'll handle... if they are "distance in meters", it still depends if you measure the distance between electrons or between galaxies (or a mix of the two).

james_lohr

If you don't have any suggestions about how to achieve what I have plainly asked for numerous times

We're informing you that you're trying to achieve the wrong thing. We know this because you have repeatedly demonstrated your understanding to be flawed.

Quote:

Negative powers of 2 do not have more precision than negative powers of 10, otherwise they could represent more numbers than negative powers of 10 could, which they can't.

I just explained to you that, for the same amount of memory, base 2 numbers do represent more real numbers than base 10 numbers. It just so happens that base 10 can (unsurprisingly) represent decimal numbers exactly - but who care? This is a minuscule subset of the set of real numbers. If you want to evaluate arbitrary mathematical expressions, then base 2 will do the job better on a computer than decimal.

If they were represented as sums of any base greater than 1 with powers greater than or equal to 0 with a decimal point and exponent tracked separately, then any rational number could be represented exactly by them. The entire problem stems from the fact that negative powers are used to represent numbers less than one.

That's the type of naive approach to representing real numbers that students come up with in their introductory lessons to understanding floating numbers. Usually the majority of students have managed to grasp the elegance of base 2 floating point numbers within a few lectures. Of course, there are some who don't. :P

I think your problem is that you are so used to seeing and using decimal numbers that that is what a number is to you. If you study mathematics or computer science at degree level, you will almost never see decimal numbers, and the few times that you do, they are crude approximations of real numbers (e.g. 3.14) used for crude calculations.

orz

Any real number that is rational can be represented in base 10. The same can't be said for base 2 unless you use positive powers to represent the number and track the exponent.

As has already been pointed out in this thread, there are rational real numbers that cannot be represented in base-10 with non-repeating digits (1/3rd was previously mentioned, but any simple integer fraction with a divisor that has any prime factor other than 2 or 5 also qualifies).

Use of "positive powers to represent the number and track the exponent" (ie a decimal point and/or scientific notation aka floating point) is generally equally necessary or unnecessary for binary or decimal representations.
It is (sort of) true that a wider variety of numbers can be represented exactly without repeating digits in decimal than binary since 10 has more prime factors than 2, but that does not mean that base 10 is more precise, and if you desired that basic property then you would be better off using base 210 than base 10 (as 210 has a wider variety of prime factors than 10 or 2). Such base are neither more nor less precise because for any fixed amount of information the number of values that can precisely be represented is the same.

The only significant advantage to decimal on modern computers is that it is often less complicated to interface to other decimal systems (ie input or output to/from human-readable decimal sources, standard decimal precisions/rounding rules in financial codes, etc). There are numerous strategies for dealing with the binary-decimal interface issues, and they mostly work well.

Your discussion of the subject repeatedly appears to show a misunderstanding of the concepts involved, though it is hard to tell for sure how much is miscommunication vs misunderstanding.

The binary-vs-decimal issues are almost completely unrelated to fixed-vs-floating point issues, fixed-vs-variable-vs-infinite precision issues, etc.

Edgar Reynaldo

My post is too long for a.cc to process correctly, so I had to leave out some quotes relevant to my responses. Sorry about that.

Evert said:

Edgar said:

You're contradicting yourself. First you say they're equally valid and then you admit that powers of 10 can represent more numbers than powers of 2.

That's not a contradiction.

Of course it is a contradiction. If you can represent more natural numbers with one base than you can with another, that makes the other base less valid as a choice for what you want to use.

Evert said:

Edgar said:

Are powers of 10 a better representation of numbers than powers of 2 or not? Well, yes they are.

No they're not.

Powers of 10 can represent more numbers than powers of 2, so they are a better representation of numbers.

Evert said:

Edgar said:

Floating point numbers are broken if they can't represent a decimal string exactly.

No they're not. They would be if they couldn't represent a binary string exactly, but they can. Computers use binary, not decimal.

Computers may use binary, but guess what - computers are intended for human use, and humans use decimal. So for mathematical purposes, they are broken.

Evert said:

Edgar said:

I've said numerous times that I expect a string to be represented exactly in data format and to get the same string out when converting back. Why do I have to keep saying this?

Because you keep not getting that you're spouting nonsense?

You're the one spouting nonsense. Expecting perfect string decimal to data conversion and back is a reasonable expectation for my purposes. There's no good reason that 5.1/0.1 should ever equal something other than 51. You act as if I expect the common implementation of floating point numbers to do what I want it to do. I've said more than once I'm looking for a data type that will perfectly convert to data and back to string, so it should be completely obvious by now I'm not intending to use conventional floating point numbers. If you don't get that, too bad.

Evert said:

What's not true? The number of even integers being the same as the total number of integers? Shows your ignorance if that's what you meant.

There are always twice as many total integers as there are even integers. The fact that the count of both approaches infinity is irrelevant.

Evert said:

And yes, x = x+n can be true if x is infinite.

No, it can't. Subtract infinity from both sides and you have 0 == n? Since the condition was that n is non-zero, it is obvious 0 doesn't equal n. Infinity + 1 is not infinity. Infinity times 2 is not infinity. The entire number system breaks if you treat it that way, so I won't.

Evert said:

Edgar said:

I understand I can't exactly represent irrational numbers. I'm not trying to either.

No, but you're trying to do something analogous.

Representing exact decimal numbers exactly in data is not analagous to representing irrational numbers.

@ Audric
Here's what I originally asked for :

Edgar said:

When scanned, "#.#" has to equal #.# - ie... "5.1" has to equal 5.1 when scanned from a string. Because currently if I use sscanf on "5.1" to get a double and then printf the double back out with high precision, it is 5.0999999999999996 instead of 5.1, and this occurs far too often with other numbers as well, even if it is only off by 4e-16 or so. I want to be able to move from string to double and back without losing any precision.

I may have misspoke in the last sentence when I said "to double and back", but it should have been fairly obvious that I meant "to data and back", however it would be represented. I have also clarified that several times and stated doubles aren't sufficient for my purposes, so for the last time - I want a data type that can move from string to data and back without any loss of precision. I haven't fully tested it yet, but it appears that the MAPM library can do this for me. So unless you have any suggestions for libraries that could do the same thing as well as or better than MAPM, further comments are likely pointless.

Audric said:

I'm pretty sure it was not intended with infinite number of decimal places that can be obtained during a computation (ex: 1/3), but rather for the numbers that are input by humans.

Finally! Someone who actually comprehends what I've been asking for all along.

I'm not sure what the underlying representation of the MAPM data type is, but it appears to be smart enough to know that "5.1" means 5.1 and not 5.0999999999999996. I don't believe that any rounding has occurred during conversion to data or back to string, as default precision is 30 digits, and the only rounding done is during division or else explicitly.

Audric said:

What's it for?

It is for a function expression evaluation tool. You can try out the working prototype over at the

batch files, graph plotting and

thread started by William Labbett. If you run the expression 5.1/0.1 inside the program you can see that it fails horribly at extracting an exact answer (which clearly exists). The current implementation still uses doubles as the data type, and that is why it fails. I want to test MAPM a little more before I convert everything over to the MAPM data type.

@ James Lohr
Trying to achieve accurate computations is the wrong thing? I bow to your wisdom great sir. Which part of my understanding is flawed? The part where I understand floats and doubles can't do what I want, or the part where I asked for a data type that could, or the part where negative powers of two can't represent a decimal number exactly 100% of the time?

Did you miss the part where I said I wasn't concerned about the efficient use of memory? Who cares that base 10 can represent decimal numbers exactly? Oh well, just the people who desire accurate calculations. Never mind them though. For the last time - negative powers of base 2 will never do a better job of evaluating decimal expressions than base 10 would. That's beside the point though - see my next answer to you.

What is elegant about inaccurate calculations (from the use of base 2 with negative powers)? Nothing. You're the one who's naive if you think inaccurate calculations are acceptable where accurate calculations are both possible and desired.

Decimal numbers are what the majority of people use - not binary. The only crude approximation of a real number here stems from the fact that negative powers of two are used, and they cannot accurately reflect most decimal numbers less than one.

@ orz
As I said, I'm not concerned with irrational numbers, or with infinite precision. What I am concerned with however is accurate calculations where they are possible.

Use of positive powers is necessary if you want to use base 2 to accurately represent rational decimal numbers.

If you can express more numbers in a certain base than another, then as far as I'm concerned it is more precise. That said, base 210 is unnecessary since I'm primarily concerned with accurate representation of decimal numbers.

What exactly is it that I'm misunderstanding? You all seem to think I don't understand what is going on, but I've repeatedly shown that I do, otherwise I would be satisfied with the endlessly tiresome suggestion that floats and doubles are sufficient for my needs.

Matthew Leverton

Edgar, please some day take a course on number theory (e.g., countable sets, infinity, etc) or advanced calculus (i.e., how calculus works, not how to use it), and report back to tell me how much time you spend arguing with the teacher and the textbook and what grade you ultimately get. 8-)

Some of your dogmatic statements are as incorrect as me trying to claim that 1 + 1 = 3. Seriously, you are making a fool of yourself. Trust me, your intuition of how numbers work does not cancel out the discoveries of many smart mathematicians who devoted their lives to this sort of thing. You really should just drop that part of the discussion until you take time to educate yourself.

Because of that, I don't think you're going to get any respect regarding the actual problem at hand (representing numbers in whatever computer system you are building).

Oscar Giner

There are always twice as many total integers as there are even integers. The fact that the count of both approaches infinity is irrelevant.

You're disregarding basic mathematics theory here :-X

Quote:

No, it can't. Subtract infinity from both sides and you have 0 == n?

But infinity minus infinity is not 0, it's undefined :-X

Quote:

What exactly is it that I'm misunderstanding? You all seem to think I don't understand what is going on, but I've repeatedly shown that I do, otherwise I would be satisfied with the endlessly tiresome suggestion that floats and doubles are sufficient for my needs.

That your problem can easily be solved by just using doubles, without the need to use any of those libs. All you have to understand is how floating point numbers work, and when printing a floating point number, disregard the part that doesn't have the precission required, using rounding (IIRC, 64 bit doubles have 15 significant (decimal) digits, so if you use doubles that means if you limit your output to 15 digits you'll get an exact output (the same you'd get if you used a decimal representation and print a max of 15 digits)).

In your example of 5.0999999999999996. If you only print the first 15 digits, rounding the number, you'll get 5.1 printed.

That's how calculators work (Orz explained it in his second post). This is faster (because you're using a native representation for floats), and also takes less memory (to get the same precission, you need more memory if you're using decimal representation than if you use a binary representation).

Edgar Reynaldo

Edgar said:

There are always twice as many total integers as there are even integers. The fact that the count of both approaches infinity is irrelevant.

You're disregarding basic mathematics theory here

So 2*x = x where {x | !0}? Who's disregarding mathematics here?

Oscar Giner said:

But infinity minus infinity is not 0, it's undefined

Sorry, I prefer the real world where x - x = 0.

Treating infinity as a special number may help solve some problems in math, but I prefer to think of it as a regular number that has just gotten too large to count.

Oscar Giner said:

That your problem can easily be solved by just using doubles, without the need to use any of those libs. All you have to understand is how floating point numbers work, and when printing a floating point number, disregard the part that doesn't have the precission required, using rounding (IIRC, 64 bit doubles have 15 significant (decimal) digits, so if you use doubles that means if you limit your output to 15 digits you'll get an exact output (the same you'd get if you used a decimal representation and print a max of 15 digits)).

In your example of 5.0999999999999996. If you only print the first 15 digits, rounding the number, you'll get 5.1 printed.

That's how calculators work (Orz explained it in his second post). This is faster (because you're using a native representation for floats), and also takes less memory (to get the same precission, you need more memory if you're using decimal representation than if you use a binary representation).

Well, I can at least say that this is the first actual explanation of how to achieve what I want without using a different data type. And it was the first comment that wasn't completely condescending and derogatory, so I thank you for that. You've earned your cookie.

Still, I don't want to lose precision through rounding unless the user specifically asks for it, and I don't want to limit myself to 15 digits of precision either, so my choice to use MAPM still stands as valid.

Edgar, please some day take a course on number theory (e.g., countable sets, infinity, etc) or advanced calculus (i.e., how calculus works, not how to use it), and report back to tell me how much time you spend arguing with the teacher and the textbook and what grade you ultimately get. 8-)

Some of your dogmatic statements are as incorrect as me trying to claim that 1 + 1 = 3. Seriously, you are making a fool of yourself. Trust me, your intuition of how numbers work does not cancel out the discoveries of many smart mathematicians who devoted their lives to this sort of thing. You really should just drop that part of the discussion until you take time to educate yourself.

Because of that, I don't think you're going to get any respect regarding the actual problem at hand (representing numbers in whatever computer system you are building).

You're stuck on your high horse just like James and Evert are. Too busy insulting me to give decent explanations of why I don't need to use a different data type.

You'd think with all the time I spend on this forum helping other people with their problems without insulting them or talking down to them, that I would get some better responses here, but maybe that's too much to ask. :P

If you're all so educated and I'm so ignorant, then it's rather selfish of you to sit there and mock me instead of taking the time to educate me with actual proof instead of blatant 'you're wrong', 'you can't grasp it', 'you are naive', 'you're ignorant' statements, and this thread has seen more than its share of them already.

Matthew Leverton

Too busy insulting me to give decent explanations of why I don't need to use a different data type.

Showing you that there are the same amount of even integers as integers does nothing to show you why you do or don't need a different data type. You miss my point entirely.

My point is that you are mistaken about fundamental truths and refuse to take correction. You speak as if you understand more about mathematics than somebody who knows much more than you. (I'm not speaking of myself.)

So you insult the mathematicians among us by pretending to know more than they, and then expect them to entertain a thoughtful and meaningful discussion about the topic at hand.

For fun here's a simple proof that there are as many even integers as integers. Give me any integer, and I will provide a unique even integer that maps to it.

Given integer n, I present you an even integer 2 * n.

If there were twice as many integers as even integers then I would run out of unique even integers to pair.

Again, back to my point. If you would argue against proven mathematics (i.e., the equivalent of saying 1 + 1 = 3), then your arguments against using floats or doubles will be perceived as the same sort of stubbornness, regardless if you have valid concerns.

Edgar Reynaldo

For fun here's a simple proof that there are as many even integers as integers. Give me any integer, and I will provide a unique even integer that maps to it.

Given integer n, I present you an even integer 2 * n.

If there were twice as many integers as even integers then I would run out of unique even integers to pair.

Consider the set of integers from 1 to n where n is even. Count the number of total integers from 1 to n and the number of even integers from 1 to 2. There are n total integers and n/2 even integers. Extrapolate that as far as you want to. There are always twice as many total integers as even integers for any even n and 2x + 1 / x total integers to even integers for odd n. Your 'proof' that there are the same number of total and even integers relies on the trick of using different sets of numbers. Yes for every n there also exists 2*n, but there also exists 2*n + 1, which is odd, bringing the total ratio to 2 to one, not one to one.

Matthew Leverton

I understand your reasoning, but your proof is one of intuition and is not mathematically valid. I cannot "extrapolate as far as I want" because infinity has no bounds in that context.

My proof relies on no tricks. We have two sets of numbers:

  • Set A: all integers

  • Set B: all even integers

We want to know if Set A and Set B are the same size. The mathematical way to prove that is to provide a one-to-one function that maps a single element in A to a unique element in B (and B to A.)

I have provide such a function (although admittedly I have not actually proved that it is one-to-one and onto, but I don't think you are disagreeing with that). It is mathematically sound, and covers the range of everything in the two sets we are discussing.

If you wish to argue, then we aren't even speaking the same language. Mathematics has rules, and if you don't wish to follow them, then there's no common ground for discussion.

I won't try to explain it to you any further. I'm not trying to be "insulting," but I cannot explain an entire course on number theory in a handful of posts. (And it's not like I remember much of what I once learned anyway...)

Here's a small article to get you started.

Edgar Reynaldo

There are in truth three sets :
A - All integers
B - All even integers
C - All odd integers

Set A is by definition the union of B and C since there are only odd and even integers.

Map set A to B and set A to C :
Bn = 2*An
Cn = 2*An - 1

This gives example sets of :
A = {1,2,3...}
B = {2,4,6...}
C = {1,3,5...}

So for all integers in A from 1 to n there are n corresponding elements in both B and C. Since B and C are the same size, and A is the union of B and C, the actual size of A will always be 2*B. The proof that there is a 1 to 1 relationship between A and B and A and C is superseded by the definition that A is composed of the union between B and C. You can't say that A is not the union of B and C because that is the definition of 'all integers'.

The size of A can't simultaneously equal both the size of B and the size of the union of B and C. The only remedy to this contradiction is to stick with the definition of A as the union of B and C.

In truth, it is a paradox.

Matthew Leverton

the actual size of A will always be 2*B

You are dealing with infinite set, so that is not an operation that means that A is not the same size as B.

You are saying something like:

  1. I have infinite sets A, B, C.

  2. A is proven to be the union of B and C

  3. A is proven to be the same size as B

  4. A is proven to be the same size as C


  5. Based on my intuition of how I think infinite sets operate, I declare the mathematical proofs to be invalid.

You cannot throw your hands up at the conclusion and say "it cannot be." You must reshape your beliefs on what you have proven to be correct. Or you must show that you have incorrectly proven one of steps 1 to 4.

Your intuition that the result is a paradox because of your knowledge of how finite sets operate is not sufficient proof.

Quote:

The size of A can't simultaneously equal both the size of B and the size of the union of B and C.

That's really just circular reasoning. That's precisely the statement that we are trying to prove. It's must like saying "1 + 1 does not equal 3 because 1 + 1 does not equal 3".

It can simultaneously be the same size if you can find a function that maps A to B and a function that maps A to B union C.

I present a simple mapping function for the latter:

  • n => n

And we already have n => 2 n for set B, so now we have proven what you said is impossible.

Quote:

In truth, it is a paradox.

You may find this interesting. A relevant piece:

Quote:

However, in Hilbert's aptly named Grand Hotel, the quantity of odd-numbered rooms is as many as the total quantity of rooms. In mathematical terms, the cardinality of the subset containing the odd-numbered rooms is the same as the cardinality of the set of all rooms. Indeed, infinite sets are characterized as sets that have proper subsets of the same cardinality.

Edgar Reynaldo

Fine, look at it from other direction. Map all even numbers less than or equal to 2n to all integer numbers less than or equal to 2n. You can't do it.

A all integers from 1 to 2n
B even integers from 2 to 2n by 2

A 1 to 2n
B 2 + 2...2n

An = Bn/2

B {2,4,6...}
A {1,2,3...} OOPS {4,5,6} is missing from A

There are n numbers in B and 2*n numbers in A. Their cardinality is not the same. You have to consider the range of the set, even if you extend it to infinity.

Maybe there are special rules to deal with infinite sets, but I prefer to deal with infinite sets as if they are impossibly large finite sets. If that's not PC, oh well.

Matthew Leverton

A all integers from 1 to 2n
B even integers from 2 to 2n by 2

That's not an infinite set. You are bounding it by '2n', so of course A is twice as big. But if Set A is the set of all integers, and Set B is the set of all even integers, then the mapping from B to A looks like. n => n / 2.

Quote:

Maybe there are special rules to deal with infinite sets, but I prefer to deal with infinite sets as if they are impossibly large finite sets. If that's not PC, oh well.

It's not about being politically correct, it's about being mathematically correct.

If you want to deal with "impossibly" large sets, then use this notation: {1, 2, ..., N}. However, that is not the same as infinite sets. Any conclusion you draw from such sets does not apply to infinite sets, even if N is really, REALLY big!

You can not entertain a discussion that is intrinsically mathematical and then decide on using your own definitions and rules, and expect any sort of favorable outcome.

orz

You all seem to think I don't understand what is going on, but I've repeatedly shown that I do, otherwise I would be satisfied with the endlessly tiresome suggestion that floats and doubles are sufficient for my needs.

The problem is you're repeatedly showing that you don't understand what you're talking about and/or you're speaking Martian. Some of your comments make perfect sense, like "base 210 is unnecessary since I'm primarily concerned with accurate representation of decimal numbers". Others of your statements are confusing &| incoherent like "As I said, I'm not concerned with irrational numbers, or with infinite precision" (in response to a post of mine that clearly was not talking about irrational numbers or infinite precision), or wrong like "Use of positive powers is necessary if you want to use base 2 to accurately represent rational decimal numbers" (depending upon how I interpret that it's either clearly false or true on a technicality but very very strongly implying things that are false), or wrong as written but maybe if I interpret a bit creatively then it could be right, like "If you can represent more natural numbers with one base than you can with another, that makes the other base less valid as a choice for what you want to use" (all natural numbers can be expressed exactly in all bases... maybe you meant real numbers?).

Anyway, focusing on the purely practical end of things, you have never commented on the very simple, easy, & common technique I described in my first post back on the first page (another person had already recommended the same technique, but he was confused and did not understand the nature of the technique). If you are willing to accept a tiny loss of precision and a substantial loss of efficiency then a slight variation on that can get you even more decimal-like behavior without much extra complexity.

Edgar Reynaldo

That's not an infinite set. You are bounding it by '2n', so of course A is twice as big. But if Set A is the set of all integers, and Set B is the set of all even integers than, the mapping from B to A looks like. n => n / 2.

Make n infinite then. You have to keep indefinitely extending the set to make it fulfill your mapping.

{2,4,6...2n}
{1,2,3...n} OOPS {n + 1,n + 2...2n} Is missing!

I guess we have to go up to 4n, I mean 8n, I mean 16n, so on, so forth, forever and ever over again...

You're comparing unequal ranges of numbers. Of course you can say that for every number n there also exists a number 2n, but that doesn't prove for every set of numbers from 1 to n there also exists n numbers from 2 to n by 2.

It just doesn't cut it for me. Sorry.

Matthew Leverton said:

If you want to deal with "impossibly" large sets, then use this notation: {1, 2, ..., N}. However, that is not the same as infinite sets. Any conclusion you draw from such sets does not apply to infinite sets, even if N is really, REALLY big!

Well then if that's the way mathematicians deal with infinite sets, then I don't want any part of it, because it's just screwed up.

The cardinality of {2,4...2n} will never equal the cardinality of {1,2...2n}. It just doesn't hold up.

If you can find me a proof that 2*infinity == infinity, then maybe I'll shut up about this. Otherwise, it's probably not likely.

Append for orz
I posted after you did, but hadn't read it yet.

orz said:

Others of your statements are confusing &| incoherent like "As I said, I'm not concerned with irrational numbers, or with infinite precision" (in response to a post of mine that clearly was not talking about irrational numbers or infinite precision)

That was in response to this :

orz said:

As has already been pointed out in this thread, there are rational real numbers that cannot be represented in base-10 with non-repeating digits (1/3rd was previously mentioned, but any simple integer fraction with a divisor that has any prime factor other than 2 or 5 also qualifies).

Sorry if it was confusing or not matched to the topic. But it mostly applies, as I'm not interested in precisely representing rational fractions. If I wanted that, I would be looking for a fraction library, not an arbitrary precision library.

orz said:

wrong like "Use of positive powers is necessary if you want to use base 2 to accurately represent rational decimal numbers" (depending upon how I interpret that it's either clearly false or true on a technicality but very strongly implying things that are false),

Can you represent one tenth exactly using negative powers of 2? No. That's why I said that.

orz said:

or wrong as written but maybe if I interpret a bit creatively then it could be right, like "If you can represent more natural numbers with one base than you can with another, that makes the other base less valid as a choice for what you want to use" (all natural numbers can be expressed exactly in all bases... maybe you meant real numbers?).

I guess I meant all real numbers that don't repeat. Sorry for the confusion.

orz said:

Anyway, focusing on the purely practical end of things, you have never commented on the very simple, easy, & common technique I described in my first post back on the first page (another person had already recommended the same technique, but he was confused and did not understand the nature of the technique). If you are willing to accept a tiny loss of precision and a substantial loss of efficiency then a slight variation on that can get you even more decimal-like behavior without much extra complexity.

I guess you were referring to this :

orz said:

If you only care about destringifaction+stringification not producing the original value, simply limiting every decimal stringification to 14 digits meets your requirements well over a fairly wide range of numbers, though that's actually a decrease in precision.

I guess I didn't actually know what that entailed, as I wasn't thinking of the number being rounded that way. Sorry if it seemed like I ignored you, I just wasn't perfectly clear on what that actually meant.

In any case, see my response to Oscar Giner, as it applies equally as a response to you :

Edgar said:

Still, I don't want to lose precision through rounding unless the user specifically asks for it, and I don't want to limit myself to 15 digits of precision either, so my choice to use MAPM still stands as valid.

Matthew Leverton

I guess we have to go up to 4n, I mean 8n, I mean 16n, so on, so forth, forever and ever over again...

Keep doing that. You'll never reach infinity.

Quote:

Make n infinite then

That makes no sense. You don't understand what infinity means in mathematical terms.

Quote:

Of course you can say that for every number n there also exists a number 2n, but that doesn't prove for every set of numbers from 1 to n there also exists n numbers from 2 to n by 2.

I don't disagree.

Quote:

Well then if that's the way mathematicians deal with infinite sets, then I don't want any part of it, because it's just screwed up.

Your lack of understanding doesn't make it "screwed up." Not wanting "any part of it" simply makes you ignorant and a waste of time to help in these matters.

Quote:

It just doesn't cut it for me. Sorry.

Your ignorance doesn't offend me... you don't have to apologize. It's actually good to let people know that you reserve the right to reject any proven mathematical principle on the basis that it upsets your belief system.

Edit:

It goes back to my original statement: Please take some advanced (theory) mathematics courses in a higher education setting and let me know how it goes. I seriously would be interested in any recordings you could provide of you discussing your disbelief with your Ph.D. equipped math professor.

I would love to find out if you could solve all the problems and proofs by using whatever mathematical system you have contrived. If so, then you're a much smarter person than I am. I got a bachelor's degree in math as an "A student," but I cheated by using the well tested mathematical truths of old as opposed to my own inventions.

It's good to be inquisitive and to "prove all things" but to live in denial is, well, basically pathetic.

Edgar Reynaldo

@orz
See my edit in my last post.

Edgar said:

I guess we have to go up to 4n, I mean 8n, I mean 16n, so on, so forth, forever and ever over again...

Keep doing that. You'll never reach infinity.

So the value 2n as n approaches infinity doesn't equal infinity then? Neat trick.

Matthew Leverton said:

That makes no sense. You don't understand what infinity means in mathematical terms.

Enlighten me then. What does infinity really mean?

Matthew Leverton said:

Edgar said:

Of course you can say that for every number n there also exists a number 2n, but that doesn't prove for every set of numbers from 1 to n there also exists n numbers from 2 to n by 2.

I don't disagree.

Then WTF are we talking about?

Matthew Leverton said:

Your ignorance doesn't offend me... you don't have to apologize. It's actually good to let people know that you reserve the right to reject any proven mathematical principle on the basis that it upsets your belief system.

Ah... Back to condescension. There's the old Matthew. I wondered where you went. You were actually being quite generous in your explanations there for a while. I knew it couldn't last though.

I will freely admit that the way infinite quantities are dealt with bothers me. If that makes me an imbecile in your eyes so be it. Meh.

Matthew Leverton

I will freely admit that the way infinite quantities are dealt with bothers me. If that makes me an imbecile in your eyes so be it. Meh.

It is fine to not understand. There's plenty of things I never understood, and never will. But assuming it is nonsense because you don't understand it is where the ignorance sets in.

Quote:

What does infinity really mean?

In this context, an infinite set is one that does not have a finite number of elements. If you say something has N elements, then it is surely not infinite.

Quote:

Then WTF are we talking about?

There are the same "number" of even integers as odd integers as total integers. (Edit: added the quotes, since it's really the cardinality that is being discussed.)

Building an argument contrary to that by using increasingly larger finite sets is an understandable attempt, but ultimately it is irrelevant. The sets we are dealing with here are infinite.

This is a fundamental concept that you are refusing to accept. Yes, it is extremely counterintuitive. Infinity is a strange concept. Embrace it in all its glory and you'll learn why 1/3 = 0.333... and 2/3 = 0.666... and subsequently 0.333... + 0.666... = 0.999... and ultimately get to 0.999... = 1.

Quote:

You were actually being quite generous in your explanations there for a while.

There's nothing more to add when your conclusion is "screw mathematics."

I'm simply telling you how I perceived you to be. If I am wrong, then, well, I was bound to be at some point.

Edgar Reynaldo

There are the same number of even integers as odd integers as total integers.

Building an argument contrary to that by using increasingly larger finite sets is an understandable attempt, but ultimately it is irrelevant. The sets we are dealing with here are infinite.

The set of all even integers is a subset of the set of all integers. It can never have the same cardinality. It just doesn't make any fucking sense.

Matthew Leverton said:

This is a fundamental concept that you are refusing to accept. Yes, it is extremely counterintuitive. Infinity is a strange concept. Embrace it in all its glory and you'll learn why 1/3 = 0.333... and 2/3 = 0.666... and subsequently 0.333... + 0.666... = 0.999... and ultimately get to 0.999... = 1.

Perhaps. I'll just have to take your word for it. Just stop telling me that 2*infinity equals infinity so my brain stops hurting.

tobing

Gosh, what a wonderful "discussion". How I love it...

It reminds of the fact that at each mathematical institute on this world, you have to deal with letters and their authors, who claim to have solved squaring the circle, or proved that sqrt(2) is not irrational, or found the ultimate world formula. It's all the same, just ignoring basic mathematical rules. Mathematicians (and philosophers) have been thinking hard about infinity for centuries, and the subject IS hard to grasp. You need the right concepts, and wrap your mind around sometimes strange thoughts. No wonder mathematicians had a hard time understanding this, and all the paradox stuff that hides inside.

Follow the two references into wikipedia, they are a good start to a long journey. If you want to understand, that is...

http://en.wikipedia.org/wiki/Countable_set
http://en.wikipedia.org/wiki/Hilbert%27s_paradox_of_the_Grand_Hotel

Arthur Kalliokoski

"Infinite" breaks down to "in" (meaning not) and "finite", meaning, well, finite. (or countable). If you could point out a number and say "that's infinity" all I have to do is add one to it to disprove that.

Just stop telling me that 2*infinity equals infinity so my brain stops hurting.

Look at it this way, you'd have to travel an infinite distance to sail a ship off the end of the world. Going twice as fast won't help.

BTW, that library I offered earlier uses binary, so I guess you wouldn't want it.

[EDIT]

This is the routine that decides how many decimal digits can be printed with reasonable accuracy in my bignum lib. I limited the digits to less in the trig example above to preclude someone else coming along and saying "I found an incorrect digit at the end of the 3rd result" or something.

void bn_maxdecset(void)
{
  double tmp;
  //log10(256) ~= 2.4082 but practically it leaves junk at the end
  bn_maxdec = (double) bn_fracbytes * 2.4082;
  //printf("\norgmaxdec = %d",bn_maxdec);
  tmp = (log(bn_fracbytes ));
  tmp *= 1.5;
  tmp = floor(tmp);
  bn_maxdec = (double) bn_maxdec - tmp;
  //printf("\nnew maxdec = %d\n",bn_maxdec);
  //fflush(stdout);
}

tobing

There are three different concepts involved here, and intermixed in mathematically invalid ways: cardinality, ordinal numbers, and approximation by an infinite series (which is what a good part of calculus is about).

When you talk about infinity and countable sets, stick to cardinality. Which is well explained in that wikipedia article about countable sets. In terms of cardinality, it is indeed true that 2*NN=NN, where NN denotes the cardinality of the natural numbers, here commonly referred to as infinity. ;)

When you talk about 0.9999....=1, that is actually a statement about approximation, and is in fact stating that the series of numbers 0.9, 0.99, 0.999, 0.9999, ... etc. ad inf. ultimately converges to 1, in terms of the limes (or limit) in sense of calculus.

Edgar Reynaldo

In mathematical terms, the cardinality of the subset containing the odd-numbered rooms is the same as the cardinality of the set of all rooms.

This is what I can't grasp.

Arthur Kalliokoski

Consider this: A line a centimeter long has an infinite number of points in it. If you doubt this, specify two points that are "infinitely close together" and I'll just get the average distance from one end.

On the other hand, a square centimeter in area has an infinity of lines at 90 degrees to one edge, is this "more" infinity or not? We can move up to a cube that measures 1cm^3 if you like.

Or going back to the square centimeter: Not only does it have an infinity of straight lines parallel to each edge, but it also has an infinity of lines at arbitrary angles. As well as an infinite amount of parabolic arcs. Extend this to the cube. And yet the centimeter line segment has "just as many" points as these other things in a cube. Or at least you can never run out.

tobing

Oops. Be careful here: If you talk about a line of 1cm, you talk about real numbers, not natural numbers. But, real numbers do have a different cardinality than natural numbers, which amounts to a mathematical proof (originally given by Cantor) that there are indeed more real numbers than natural numbers. So the real numbers do have a different, and greater, cardinality than natural numbers!

In contrast, the rational numbers have the same cardinality as the natural numbers. For a proof (which is giving an bijective map between the two sets) again see Cantor.

Want some more?

It was for a long time unknown if there is any cardinality between the natural numbers and the real numbers. This is known as Cantor's continuum problem. The answer is quite unexpected, and again goes very deep into mathematical logic: You can have both answers... in terms of commonly accepted axioms Cantor's continuum hypothesis is not decidable. That is, you can neither prove it nor disprove. This goes back to the work of Kurt Gödel during the 1930s or so.

james_lohr

Another point I forget to mention: There is a proof that states that it is possible to represent any real number exactly with an infinite sum of increasing negative powers (binary or decimal). Therefore if memory and computation is not part of the equation, then it is possible to represent your decimal values exactly using infinite floating point numbers. This is of course hypothetical, since no computer has an infinite amount of memory, but it's no less hypothetical than your grounds for using decimal over binary.

tobing

The infinite sum is, to be a tiny little bit more precise, a notion for an (infinite) series of numbers that converges to the desired real number. Which is again approximation, where you can approximate the real number to any given degree of exactness by the numbers of that series. Which again means that 1) you don't get the exact value, and 2) you need more members of the series to achieve a better approximation...

William Labbett

This is what I can't grasp.

Isn't is simple ?

You've got an infinite number of rooms. Which means no matter how many you use, there'll also be more of them spare.

You just consider the odd numbered ones : you've still got the same situation. You won't run out of empty rooms no matter how people want to stay in them.

Edgar Reynaldo

This also bothers me (infinite guests in an infinite roomed hotel leaving ??? empty rooms?) :
<math>\infty - \infty \not\equiv 0</math>

@James Lohr
I think this
Coinductive definitions and real numbers
might be what you were looking for. In any case it is moot since we don't have infinite resources to compute with.

Even given that information, it is still far simpler to represent one tenth in decimal than binary. :P

Tobias Dammers

This is what I can't grasp.

It's quite simple. In layman's terms: If you want to count all the even-numbered rooms, you'll never finish. If you want to count all the rooms, you'll also never finish. That's what cardinality is about (in simplified terms).

Using the 2n proof: If you want to show that any whole number n exists for which 2*n does not exist, then you will have to walk the list of whole numbers and check each one, until you reach one that you cannot multiply by 2. If you do this, you will never stop walking the list, because it does not end.

Infinity is not a number, not even an incredibly large one. It's a concept. And because of this, the rules that apply to numbers do not apply to infinity. You cannot subtract anything from infinity, in fact, you cannot perform any arithmetic on it at all. It's not a number.
Mathematicians use the concept of infinity and the infinity symbol to indicate a series that does not end, or a number that grows without bounds ("approaches infinity" means just that).

Back to your original problem. Computers use binary numbers to do their calculations, which means they can, by nature, only deal with whole numbers (and a limited range of them at that). However, most things in life don't map nicely to whole numbers, so people invented a bunch of strategies to overcome this problem:

  • Big integers. This strategy uses an array of integers, each representing a part of the number; the array grows as needed, so there is no theoretical maximum to the size of the number you can represent this way. You're still bound to whole numbers only, and the amount of available and addressable RAM is of course still a constraint.

  • Fractions. Store each number as a pair of integers (or better yet, bigints), one for the numerator and one for the denominator. This way, you can represent all rational numbers (again, within the physical constraints of the hardware), but there are quite some limitations - the representation isn't automatically canonical (e.g. doing 2/3 * 3/2 naively will yield 6/6, which you want to reduce to 1/1 for all sorts of reasons), and canonicalizing your numbers can be quite costly. Also, finding good approximations for irrational numbers is really really complex matter.

  • Fixed-point. Store your number as an integer, but adjust your calculations so that it is understood to mean multiples of a step < 1. For example, 1/0x10000 used to be popular (giving you a binary fixed-point format with 16 bits for the whole-number part and 16 for the fractional part); for financial calculations, you rather want to use 1/100 or 1/10000, so that your integer represents cents or 1/100ths of cents. The advantage of this is that it's very fast (you do your calculations on native integers), and your precision is exactly the same over the entire range, in absolute terms - that is, adding 0.1 to a number always produces the same rounding error no matter what you add it to.

  • Floating-point. Store your number as a pair of integers, one for the mantissa and one for the exponent. This pair (m,e) is then understood to mean m * 2e, where both m and e may be negative. (Technically, it's implemented a tad bit different, but the general idea is the same). What this means is first of all, that the precision is roughly the same over the entire range, in relative terms. That is, if a certain number has a 0.01% rounding error when represented as a float, then ten thousand times that number will also have a 0.01% rounding error, approximately.

And now comes the problem. While each of these can represent a particular subset of the set of real numbers, none of them can represent them all. One can at least represent all rational numbers, the rest of them can't even do that. All but the fraction approach have one numeric base for which they can offer exact representations, while all other rational numbers can only be approximated.

William Labbett

This also bothers me (infinite guests in an infinite roomed hotel leaving ??? empty rooms?) :

No, an infinite number of guest would match an inifinite number of rooms 1 for 1.

Oscar Giner

{2,4,6...2n}
{1,2,3...n} OOPS {n + 1,n + 2...2n} Is missing!

But those are finite sets. An infinite set doesn't have a last element (or it can have a last element, but then it cannot have a first element (for countable sets, which those both are)). So for those sets to be infinite, elements n+1, n+2... do actually exist.

So what you actually have is:
{2, 4, 6... 2n...}
{1, 2, 3... n...}

Quote:

The cardinality of {2,4...2n} will never equal the cardinality of {1,2...2n}

Of course the cardinality of {2,4...2n} is less than the cardinality of {1,2...2n}. But you did the same mistake: those are finite sets, not infinite.

And no, saying that n = infinite is not valid, because that would make you claim that an infinite set has a last element (thus not being infinite... so... are you saying that infinite sets are not infinite?).

The error you're doing again and again is extrapolating rules that apply to finite sets to infinite sets. You're trying to "prove" your believes on infinite sets by proving those believes are actually true for finite sets.

Edgar Reynaldo

Think about it this way. We all know in a finite set of integers from 1 to 2n there are 2n integers and n even integers. Why does this suddenly stop being true when you can no longer count n? It's just not right.

Evert

Why does this suddenly stop being true when you can no longer count n?

It does. You can easily show that it does. There's no more to it than that.
Consider the set N of all integers. Now construct a new set, E, such that E = {2n, for all n in N}. How many elements are there in the set E (what is the cardinality of E)? Well, the same as there are in N, by construction. However, also by construction, E contains all even integers. Conclusion: there are as many even integers as there are integers.
Similarly, construct the set O such that O = {2n+1, n in N} and lets say that 0 is in N. By construction, O has the same number of elements (same cardinality) as N. They're also all odd integers. Conclusion: there are as many odd integers as there are integers.
Suppose there are more integers than even integers. Then there must be an n in N for which 2n is not in E. But 2n is an even integer if n is an integer, and must be in E. Therefore there is no n in N for which 2n is not in E, and the number of elements in N is not larger than the number of elements in E.

Quote:

It's just not right.

It's 100% right. It's just counterintuitive (or rather, you don't have the right kind of intuition). If you want to raise an objection, find a fault in the logic of the proof. "I don't understand how this works" is not a valid objection.
So if you want to continue the debate, I suggest you try to find an error in the proof. Actually, I don't really suggest that you waste your time trying to do that. You're better off dropping this here.

Edgar Reynaldo

What's the limit of (2n/n) as n approaches infinity? Two. You'd have me believe it suddenly stops being 2 and becomes 1. That's hogwash.

Like I said before, you're comparing unequal ranges :
A {2,4,6...}
B {1,2,3...} OOPS We didn't bother to include 4,5,6. Guess we have to extend the range of A to {...8,10,12} OOPS we forgot to include 7-12 in B. Repeat ad nauseam...

The idea that there are twice as many integers as even integers cannot simultaneously be both true and false.

Don't try to convince me further. Arbitrarily breaking rules that apply to countable numbers just so uncountable numbers will work is crap.

Matthew Leverton

Closing thread to save somebody from wasting time with a response.

Thread #607410. Printed from Allegro.cc