Bug 5971 – Some BigInt ideas

Status
RESOLVED
Resolution
FIXED
Severity
enhancement
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2011-05-09T15:29:23Z
Last change time
2017-09-07T12:06:43Z
Keywords
bootcamp
Assigned to
No Owner
Creator
bearophile_hugs

Comments

Comment #0 by bearophile_hugs — 2011-05-09T15:29:23Z
[idea 1 and 2] I'd like this very simple code to work: import std.bigint, std.conv; void main() { text(BigInt(1)); to!string(BigInt(1)); } ---------------------------- [idea 3] I'd like this very simple code to work, thanks to a T opCast(T:bool)(){} member function: import std.bigint; void main() { BigInt x = BigInt(0); if (x) {} } ---------------------------- (The ideas 4 and 5 have a lower priority, because they are less commonly useful.) [idea 4] I'd like this code to work: import std.bigint; void main() { BigInt b = BigInt(10); auto result = b & 1; } --------------------- [idea 5] Sometimes I like to know how many decimal digits a BigInt is long. Currently (DMD 2.053beta) this is the best way I have found to do it: import std.bigint; void main() { BigInt b = BigInt(91) ^^ 35; const(char)[] bstr; b.toString((const(char)[] s){ bstr = s; }, "d"); int ndigits_b = bstr.length; } But a specific method avoids to keep all the decimal digits: import std.bigint; void main() { BigInt b = BigInt(91) ^^ 35; int ndigits_b = bstr.numDigits(); } (Optionally a base for numDigits(), that defaults to 10.) -----------------------
Comment #1 by bearophile_hugs — 2011-05-10T10:26:07Z
[idea 6] I'd like this code to work: import std.bigint; alias BigInt T; // Error //alias int T; // OK void main() { T x = 1; T y, z; y = z = 1; }
Comment #2 by clugdbug — 2012-06-22T00:16:57Z
Re idea 5: To find number of digits of x, use p = x.ulonglength(); m = peekUlong(p-1); then number of digits is between lowerbound = log10(m) + p*log10(ulong.sizeof*8*2). upperbound = log10(m+1) + p*log10(ulong.sizeof*8*2) Make sure that there are enough digits in m that (upperbound-lowerbound) < 1. Optionally use m = m*(ulong+1) + peekUlong(p-2), p-- to get a better value for m, which will reduce the probability that an exact calculation must be performed. If the range includes an exact integer (eg, the range is 1547.8 .. 1548.2) then it's necessary to do a full calculation. if (trunc(lowerbound) == trunc(upperbound)) return lowerbound else { y = 10^^(lowerbound+1); if (x < y) return lowerbound; return lowerbound+1; } The problem is, that if the number is close to 10^^d, there is no way to avoid the full calculation. And unfortunately, although the hard case it is numerically rare, it is a very common case in practice.
Comment #3 by razvan.nitu1305 — 2017-09-07T12:06:43Z
Ideas 1-4 and 6 are all compiling and running successfully on git HEAD. Regarding idea 5, I'm not sure that it should be standard library code. Closing as fixed.