why the inconsistency?

B

Ben Finney

21

But the correct answer is 20, not 21. The reason the
answer is wrong

18446744073709551616L

Why is the "L" there? I thought "L" isn't used anymore?

You want to perform two operations; make them explicit.

# Convert number to string representation
foo = "%d" % ( 2**64 )
# Get length of string
print len( foo )

As you've pointed out, a number has no inherent string representation
(and thus no length); choose one explicitly (e.g. by string formatting).
 
M

mensanator

I just installed Python 2.3 (upgrading from 2.1).

Version 2.3 is noticably faster and the automatic
conversion to long integers is very handy:
18446744073709551616


But if I want to know how many digits 2**64 has, I can't
just do
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
TypeError: len() of unsized object

So instead, I did this
21

But the correct answer is 20, not 21. The reason the
answer is wrong
18446744073709551616L

Why is the "L" there? I thought "L" isn't used anymore?
 
B

Ben Finney

18446744073709551616L

Why is the "L" there? I thought "L" isn't used anymore?

To answer this directly: because you've asked for the result of

repr( 2**64 )

which, as demonstrated, is showing you that the number is stored as a
long integer (since the point of repr() is to show you information about
the type of the object as well as its value).

I believe the `foo` syntax is deprecated in favour of repr( foo ), no?
If you'd used repr(), perhaps the assumption would have become
apparent.
 
J

John Hazen

I just installed Python 2.3 (upgrading from 2.1).

Version 2.3 is noticably faster and the automatic
conversion to long integers is very handy:

18446744073709551616


But if I want to know how many digits 2**64 has, I can't
just do

Traceback (most recent call last):
File "<interactive input>", line 1, in ?
TypeError: len() of unsized object

So instead, I did this

21

But the correct answer is 20, not 21. The reason the
answer is wrong

18446744073709551616L

Why is the "L" there? I thought "L" isn't used anymore?

I believe the L is there because the backticks invoke __repr__
intsead of __str__. I think backticks are somewhat deprecated
now. (At least Guido called them "a failed feature which never
got retired".)

I think what you want is 'str'.

-John
 
J

John Roth

mensanator said:
I just installed Python 2.3 (upgrading from 2.1).

Version 2.3 is noticably faster and the automatic
conversion to long integers is very handy:

18446744073709551616


But if I want to know how many digits 2**64 has, I can't
just do

Traceback (most recent call last):
File "<interactive input>", line 1, in ?
TypeError: len() of unsized object

So instead, I did this

21

But the correct answer is 20, not 21. The reason the
answer is wrong

18446744073709551616L

Why is the "L" there? I thought "L" isn't used anymore?

I believe it's scheduled to vanish in 2.4, but I could
be wrong about that.

John Roth
 
C

Christos TZOTZIOY Georgiou

On 23 Sep 2003 18:04:33 -0700, rumours say that (e-mail address removed)
(mensanator) might have written:

[snipped]
But if I want to know how many digits 2**64 has, I can't
just do

If only math.log(2**64)/math.log(10) worked with longs without
converting them into floats first... :(
 
C

Christos TZOTZIOY Georgiou

If only math.log(2**64)/math.log(10) worked with longs without
converting them into floats first... :(

And after reading the FM, if only

def count_digits(x):
return int(math.log(x, 10))

worked correctly for *all* large values, like 10**70...
 
M

mensanator

John Hazen said:
I believe the L is there because the backticks invoke __repr__
intsead of __str__. I think backticks are somewhat deprecated
now. (At least Guido called them "a failed feature which never
got retired".)

I think what you want is 'str'.


-John


Thanks to all who replied, it was very informative and helpfull. All
this is mentioned (including the discouraged use of backticks) in the
2.3 Tutorial Manual. Who knew you had to do the tutorial again?

In looking at this, I noticed that str() is EXTREMELY slow when
converting long integers to strings. Calculating f=150001! only took
about 10 minutes, but len(str(f)) took about an hour (for 711278
digits).

Lesson here is that

print len(str(f)),f

will do the string conversion twice, whereas

foo = str(f)
print len(foo),foo

will only do it once, which is handy to know when working with really
big numbers.

Thanks again.
 
M

Michael Hudson

Christos "TZOTZIOY" Georgiou said:
And after reading the FM, if only

def count_digits(x):
return int(math.log(x, 10))

worked correctly for *all* large values, like 10**70...

Um, it does :)
Traceback (most recent call last):
279.56038792470861

(10**70 is well within the range of an IEEE double).

Cheers,
mwh
 
A

Alex Martelli

Christos said:
On 23 Sep 2003 18:04:33 -0700, rumours say that (e-mail address removed)
(mensanator) might have written:

[snipped]
But if I want to know how many digits 2**64 has, I can't
just do

If only math.log(2**64)/math.log(10) worked with longs without
converting them into floats first... :(

I'm not sure how you'd compute log on integer numbers. Anyway,
if you're in a hurry to know the number of digits in 2**64 -- I
see math.log(x,10) taking about 4 usec per loop, len(str(x)) about
6.3, in each case with x=2*64 and measuring with timeit.py
(elapsed time, as I'm measuring on Linux).

gmpy.numdigits(x) repeatably takes a bit less than 2 usec per loop;
if you're interested in speedy computations with "multi-precision"
values (integers, rationals, OR floats), you could do worse than
looking into gmpy (plug, plug;-).

(Note: all times measured on my old Athlon -- I did choose an Ahtlon,
back about 30 months ago, exactly because I had seen benchmarks where
it outperformed Intel CPU's by a mile on multi-precision integral
computations, particularly with the GMP library...).


Alex
 
R

Richard Brodie

Alex Martelli said:
I'm not sure how you'd compute log on integer numbers. Anyway,
if you're in a hurry to know the number of digits in 2**64 -- I
see math.log(x,10) taking about 4 usec per loop, len(str(x)) about
6.3, in each case with x=2*64 and measuring with timeit.py
(elapsed time, as I'm measuring on Linux).

And if you're really in a hurry 64 * log10(2) is good too ;)
 
A

Alex Martelli

Richard said:
And if you're really in a hurry 64 * log10(2) is good too ;)

Yep, but it doesn't generalize to an 'x' computed elsewhere,
when all you know is that it's some big integer and need to
know how many digits its decimal representation will take.


Alex
 
A

Anton Vredegoor

Alex Martelli said:
Yep, but it doesn't generalize to an 'x' computed elsewhere,
when all you know is that it's some big integer and need to
know how many digits its decimal representation will take.

Some fast way of computing a tuple (bitmask,nbits) from a long integer
in Python can be interesting anyway, if only to facilitate bit
twiddling experiments. Below's a -probably buggy- part of a
C-extension I wrote some time ago. Now that the subject comes
reasonably close to it, maybe I can get a few stylistic hints about
this code.

Anton

static PyObject * truerand_longmask(PyObject *self, PyObject *args){
PyObject *argument, *result;
PyLongObject *v;
int i,size;
digit msd, mask, msdmask, bmask,*buffer;
if (!PyArg_ParseTuple(args, "O", &argument)){
return NULL;}
v = (PyLongObject *) PyNumber_Long(argument);
v = long_normalize(v);
size = ABS(v->ob_size);
msd = v->ob_digit[size-1];
Py_DECREF(v);
mask = BASE + MASK;
buffer = malloc(size * sizeof(digit));
for (i = size; --i >= 1;) buffer = mask;
buffer[0] = 0;
result = _PyLong_FromByteArray((char *) buffer,
size * sizeof(digit),
0, /* little-endian */
0 /* signed */);
free(buffer);
v = (PyLongObject *) result;
v->ob_size = size;
bmask = BASE;
msdmask = mask;
while (msd < bmask){
msdmask ^= bmask;
bmask >>= 1;
}
v->ob_digit[size-1] = msdmask;
return Py_BuildValue("Ni",result,size);
}
 
A

Alex Martelli

Anton Vredegoor wrote:
...
Some fast way of computing a tuple (bitmask,nbits) from a long integer
in Python can be interesting anyway, if only to facilitate bit
twiddling experiments. Below's a -probably buggy- part of a

Sure, but I think gmpy already offers good and fast functions for all of
these needs. E.g., gmpy.numdigits(x, 2) for the number of bits, and
also getbit, setbit, lowbits, ...


Alex
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,528
Members
45,000
Latest member
MurrayKeync

Latest Threads

Top