Had overlooked Fredllman's post when I made mine, or I wouldn't have made it. The same idea, and the Fredllman implementation is clearly better than mine.
What "that"?
That awful bignum I scrambled up so no one would consider it a work of art?
Or the fun thinking about how to calculate the answer to the OP's question?
Come to think of it, the log10() is not necessary, since we already know it from the user's input... and there are efficient integer pow() functions...
//----------------------------------------------------------------------------
// JLBorges
unsignedlong ndigits( unsignedlong number )
{
unsignedlong digits = 0 ;
unsignedlong nd = 1 ;
for( unsignedlong i = 9 ; number > i ; i *= 10 )
{
digits += i*nd ; ++nd ; number -= i ;
}
return digits + number*nd ;
}
//----------------------------------------------------------------------------
// Fredllman
unsignedlong numDigits( unsignedlong n ) {
unsignedlong result = 0;
for (unsignedlong p = 1; p <= n; p *= 10) {
result += n - p + 1;
}
return result;
}
//----------------------------------------------------------------------------
// Duoas
unsignedlong ipow( unsignedlong base, unsignedlong exp )
{
unsignedlong result = 1;
while (exp)
{
if (exp & 1)
result *= base;
exp >>= 1;
base *= base;
}
return result;
}
unsignedlong digits_in_1_to_N( unsignedlong n, unsignedlong w )
{
if (n == 0) return 0;
n *= w;
w -= 1;
n -= (((ipow( 10, w ) - 1) / 9) * 10) - w;
return n;
}
D:\prog\nines\times> a
Calculate the number of digits needed to count from 1 to n.
n? 489564266
iterations? 100000000
JLBorges
489564266 --> 4294967292
time = 0:05.3663 = 0:00.0000 per iteration
Fredllman
489564266 --> 4294967292
time = 0:04.9295 = 0:00.0000 per iteration
Duoas
489564266 --> 4294967292
time = 0:03.0107 = 0:00.0000 per iteration
D:\prog\nines\times>
Hmm... I suppose a "most efficient" program would choose which algorithm to apply based upon the digit-width of the input and/or failure due to machine word limitations.
I suppose a "most efficient" program would do a table look up based on the number of digits for the sum of the first n-1 terms and then another table lookup to help compute the last term. It would have no loops at all.
Edit: Come to think of it, how does one compute the number of digits without a loop? Unroll it, I suppose.
You need to use the C++11 standard (-std=c++11 on the command line).
Your GCC is too old, so you can just hack out the stuff you don't need:
1 - get rid of the typed enum stuff enum : longlong { ... } --> enum { ... }
2 - get rid of the static_assert
$ ./a.out
Calculate the number of digits needed to count from 1 to n.
n? 4294967295
(notice how n is now too big for the machine method to work properly?)
unsigned int calculated --> 41838561849
bignum calculated --> 41838561849
$ g++ 1toN.cpp
$ ./a.out
4183856185
They are not equal? Is that because of me?
EDIT: Should the bignum be correct?
If you have changed enum : longlong { ... } to enum { ... }, you are creating an integer overflow. The number 41838561849 is outside the range of the C++98 enum.
1 2 3 4 5 6 7 8 9 10
#include <iostream>
#include <limits>
int main()
{
std::cout << "max possible: " << std::numeric_limits<unsignedint>::max() << '\n' ;
unsignedlong result = 41838561849ULL ;
// *** warning: large integer implicitly truncated to unsigned type [-Woverflow]
std::cout << result << " (how could we expect the result to be 41838561849)\n" ;
}