Ah. I see the confusion.
Apples to oranges.
The way a bignum works is as a list of limbs (big digits, or bigits), which is in reality just a list of your standard integer type. And integers have an an internal working radix of 2 — which allows you to say the same of the entire number: it is a
binary value and not a
textual value.
But radix is a matter of operational structure. Again, back to the grade school discussion:
567 = 5×102 + 6×101 + 7×100
That very same number could also be represented in octal (radix = 8):
567 = 10678 = 1×83 + 0×82 + 6×81 + 7×80
Or hexacecimal (radix=16):
567 = 23716 = 2×162 + 3×161 + 7×160
No matter how you select radix,
it is the same number.
So what is the point of radix?
Convenience. We select a radix based upon what we are doing with it. If I am playing with bit patterns then I will use hexadecimal (or binary, which you can do in C++ now) because it makes it easy for me to see and manipulate the individual bits in the value.
If I am presenting a counting number to the user, such as age or gas mileage, I will use decimal, because that is what the user is familiar with.
If I ask the computer to add my two numbers, deep down underneath the hardware bit adders work in binary, because the computer works in binary.
We choose a radix based upon use.
For a bignum, we can choose any radix that is convenient.
Some bignums use decimal, and even store the digits as the Latin-1 representation. So the bignum value "567" is exactly the same as the string "567". Adding one to the value causes conversion of, say, '7' → 7, one is added, producing 8. Divide by the radix (10) to get 8/10 = 0R8. 0 is the carry. 8 is the remainder. Convert the remainder back to a Latin-1 value: 8 → '8', and store it. Continue with the next digit if carry is non-zero.
Such a bignum is wasteful, however. It uses an entire byte (256 possible values) to store a measly 10 values. So it uses more memory than necessary (“153” takes three bytes instead of the one that it would take if you were just using an int), and it takes longer to do stuff, like adding a thousand digits.
So instead of working with radix=10, choose a bigger radix. Store each element of the bignum as a word, and use a radix like, oh, say, 65536. Now I can store really big numbers really efficiently, and mathematical operations on them are so very much more efficient. A thousand digit (radix=10) number now only takes 208 words to store, which is 416 bytes, which is significantly less than 1000 bytes. Everything goes faster, and there is more of it. Win, win!
So what is the “Boost says radix 2” really saying?
Bignums have traditionally appeared both ways. Even now your webpages can make use of a popular javascript bignum that is base ten, just like I described above.
What that boost document is saying is that the numbers are not stored as text, but as integer digits. It does not (it cannot!) make any representation on what radix the bignum actually uses underneath.
And, honestly, you shouldn’t care.
But precision!
In terms of what is meant by
precision — it is a contextual word and you are confusing what it means in context. I did not know which you meant, so I spoke to the two possibilities I thought you meant. (One of them is what you do mean.) But you are confused based on a third context.
POSSIBILITY ONE
True scientific precision is based upon the accuracy of the information you have. I can get a computer to calculate a value with all kinds of digits, and say that my front door is 37.32519844 inches wide. But there is no way I measured it with such accuracy: my eyeballs and a tape measure might get me within about a quarter of an inch, for all anyone cares, so I might say that the precision of that measurement is 3 digits: 37.3. All those extra digits mean nothing.
POSSIBILITY TWO
Computers don’t care. So the
other type of precision is the kind where we ask the computer to stop spitting out digits at some point. I can say that my door-measuring is not worth more than one digit past the decimal point.
1 2
|
// Only care about one digit past the decimal point:
std::cout << std::fixed << std::setprecision( 1 ) << 3.14159265 << "\n";
|
Mind you, C++ allows you to use the
scientific version of precision as well:
1 2
|
// Only want two digits total:
std::cout << std::defaultfloat << std::setprecision( 2 ) << 3.14159265 << "\n";
|
POSSIBILITY THREE
You can ask MPFR to control its memory usage. Beyond fixing a maximum bignum size, it also allows several optimizations when dealing with the numbers.
That is what the bignum precision is for: you are asking the bignum to work over a specific number of bignum digits, because it is a waste of time and memory to work over more than that. (Context=internal representation of the bignum=limits on processing power and memory usage.)
Notably (again), it has little to do with the number of digits the computer will display to you when converting to decimal (radix=10) for
textual display (context=human readable).
So, I really am done here now...
Hope this helps.
[edit]
@
MikeStgt
“I am not convinced” means exactly the same thing as “I doubt”.
Doubt all you like. Your ignorance will not save you. I guarantee you I know more about bignums than you do, and if you don’t believe that, then... whatever. Good luck with stuff.
You now have a very good introduction to bignums that will help you to learn more. And you got it for free, instead of having to make any effort yourself. If you really care about it, go and spend some actual study time learning more than it takes to eyeball the cover page for a boost library.