2

I'd like to print an large integer without the "e+XX" at the end in Python.

For example, when I write:

n = 100
k = 18
result = 1
i = 0

while i < k:
    result = result * (n - i) / (i + 1)
    i += 1

The result is 3.066451080298821e+19, and I would like to have 30664510802988208300.

13
  • 2
    Then you should consider performing integer math. Commented Mar 16, 2017 at 16:43
  • print int(3.066451080298821e+19) Commented Mar 16, 2017 at 16:44
  • 5
    30664510802988208300 is not infinite... Commented Mar 16, 2017 at 16:45
  • 1
    Adding to @IgnacioVazquez-Abrams: Perhaps you want result = result * (n - i) // (i + 1) (floor division), not result = result * (n - i) / (i + 1); ("true" division that results in float)? (Side-note: Terminating lines with semi-colons is distinctly non-Pythonic; it's allowed, but don't do it unless you're actually putting multiple statements on a single line, which you also shouldn't do, in general) Commented Mar 16, 2017 at 16:48
  • 2
    @zephyr: In this case, none of the divisions have a remainder, so truncation isn't a problem. Commented Mar 16, 2017 at 16:55

2 Answers 2

3

If you want an integer, you have to use integer division, // instead of /, as mentioned in @farsil's deleted answer.

result = 1
k = 18
n = 100

for i in range(k):
    result = result * (n - i) // (i + 1)

print(result)

This only gives the correct result if i + 1 is always a divisor of result * (n - i). However, this is always true, so we are fine.

You cannot use / because that will perform floating-point division, which will truncate the results to 56 bits. The correct result does not fit in 56 bits:

In [1]: int(float(30664510802988208300))
Out[1]: 30664510802988208128
#                        ^^^ oops... off by 172

Why is floor division safe?

In this case, when the division by 2 is performed, we have multiplied result by n and n-1, at least one of which is a multiple of 2. When i+1 is 3, then we have multiplied by n, n-1, and n-2, at least one of which is a multiple of 3. This pattern works for all numbers.

Sign up to request clarification or add additional context in comments.

2 Comments

It takes a bit more work than that to really prove it's safe, because directly matching numbers to their multiples might "overcommit" a particular number in the numerator. For example, with n=28 and k=8, we can't match the 24 up to both 8 and 6.
@user2357112: Yes, that is really just a sketch of a proof, but it is a well-known result.
2

I think the question you really want to ask is 'how can I print a number in Python without scientific notation?'

The answer is, your number right now is a float. Try print(type(result)) and you will see it says float. You could type cast it to an integer by doing int(result), and it will show close to the full number, 30664510802988208128. It will be a bit off because of the memory size storage limitations of int vs float.

The better way to do this would be like:

result = 1
i = 0

while i < 18:
    result = result * (100 - i) // (i + 1)
    i += 1

print(result)

which will keep result as an int type. It now should print 30664510802988208300

2 Comments

This doesn't work as Dietrich Epp pointed out in the comments. Python will truncate your float and if your number is large enough, it won't actually match the true int value after you cast it.
Yeah it's a little off as Dietrich said in his answer.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.