# Re: factorial of negative one (-1)

Discussion in 'Python' started by Chris Rebert, Nov 1, 2010.

1. ### Chris RebertGuest

> On Mon, Nov 1, 2010 at 4:19 AM, Bj Raz <> wrote:
>> On Fri, Oct 29, 2010 at 1:02 AM, Chris Rebert <> wrote:
>>> On Thu, Oct 28, 2010 at 9:41 PM, Bj Raz <> wrote:
>>> > I am working with differential equations of the higher roots of
>>> > negative
>>> > one. (dividing enormous numbers into other enormous numbers to come out
>>> > with
>>> > very reasonable numbers).
>>> > I am mixing this in to a script for Maya (the final output is
>>> > graph-able as
>>> > a spiral.)
>>> > I have heard that Sage, would be a good program to do this in, but I'd
>>> > like
>>> > to try and get this to work in native python if I can.
>>> > The script I am trying to port to Python
>>> > is;Â http://pastebin.com/sc1jW1n4.
>>>
>>> Unless your code is really long, just include it in the message in the
>>> future.
>>> So, for the archive:
>>> indvar = 200;
>>> q = 0;
>>> lnanswer = 0;
>>> for m = 1:150
>>> Â lnanswer = (3 * m) * log(indvar) - log(factorial(3 * m)) Â ;
>>> q(m+1) = q(m)+ ((-1)^m) * exp(lnanswer);
>>> end
>>> q

On Mon, Nov 1, 2010 at 1:23 AM, Bj Raz <> wrote:
> Simply out of curiosity is there a way to force python to print more then 16
> places from the decimal? For better accuracy.

(1) Please don't top-post. (http://en.wikipedia.org/wiki/Top-post )
(2) The underlying double-precision floating-point number only has ~16
decimal digits of precision, so it's pointless to print out "further"
digits.
(3) If you actually need more than 16 decimal places, use something
like the `decimal.Decimal` datatype:
http://docs.python.org/library/decimal.html

Cheers,
Chris
--
http://blog.rebertia.com

Chris Rebert, Nov 1, 2010

2. ### Hrvoje NiksicGuest

Chris Rebert <> writes:

> (2) The underlying double-precision floating-point number only has ~16
> decimal digits of precision, so it's pointless to print out "further"
> digits.

A digression which has nothing to do with Raj's desire for "better
accuracy"...

Printing out further digits (without quotes) is not pointless if you
want to find out the exact representation of your number in python's
floating point, for educational purposes or otherwise. Python has a
little-known but very instructive method for determining the makeup of a
float:

>>> 1.1 .as_integer_ratio()

(2476979795053773, 2251799813685248)

1.1 is represented with the closest fraction with a power-of-two
denominator, 2476979795053773/2251799813685248. As is the case with all
Python floats, this fraction has an exact decimal representation,
1.100000000000000088817841970012523233890533447265625. It is not that
unreasonable to request that the whole number be printed, and python
will happily oblige:

>>> "%.100g" % 1.1

'1.100000000000000088817841970012523233890533447265625'

The digits after the first cluster of zeros are not garbage, at least
not in the sense of what you get reading uninitialized memory and such;
they're mathematically precise decimal digits of the number that "1.1"
has turned into during conversion to float.

Hrvoje Niksic, Nov 1, 2010

3. ### Ken WatfordGuest

On Mon, Nov 1, 2010 at 5:42 AM, Hrvoje Niksic <> wrote:
>
> Printing out further digits (without quotes) is not pointless if you
> want to find out the exact representation of your number in python's
> floating point, for educational purposes or otherwise.  Python has a
> little-known but very instructive method for determining the makeup of a
> float:
>
>>>> 1.1 .as_integer_ratio()

> (2476979795053773, 2251799813685248)
>

Handy, but if you need the exact representation, my preference is
float.hex, which seems to be the same as C99's %a format.

>>> math.pi.hex()

'0x1.921fb54442d18p+1'
>>> float.fromhex(math.pi.hex()) == math.pi

True

Granted, it's not as easy for humans to interpret, but it's useful for
certain things.

Ken Watford, Nov 1, 2010
4. ### Bj RazGuest

On Nov 1, 2010, at 5:42 AM, Hrvoje Niksic <> wrote:

> Chris Rebert <> writes:
>
>> (2) The underlying double-precision floating-point number only has ~16
>> decimal digits of precision, so it's pointless to print out "further"
>> digits.

>
> A digression which has nothing to do with Raj's desire for "better
> accuracy"...
>
> Printing out further digits (without quotes) is not pointless if you
> want to find out the exact representation of your number in python's
> floating point, for educational purposes or otherwise. Python has a
> little-known but very instructive method for determining the makeup of a
> float:
>
>>>> 1.1 .as_integer_ratio()

> (2476979795053773, 2251799813685248)
>
> 1.1 is represented with the closest fraction with a power-of-two
> denominator, 2476979795053773/2251799813685248. As is the case with all
> Python floats, this fraction has an exact decimal representation,
> 1.100000000000000088817841970012523233890533447265625. It is not that
> unreasonable to request that the whole number be printed, and python
> will happily oblige:
>
>>>> "%.100g" % 1.1

> '1.100000000000000088817841970012523233890533447265625'
>
> The digits after the first cluster of zeros are not garbage, at least
> not in the sense of what you get reading uninitialized memory and such;
> they're mathematically precise decimal digits of the number that "1.1"
> has turned into during conversion to float.

Thank you Chris.

Bj Raz, Nov 1, 2010
5. ### Lawrence D'OliveiroGuest

In message <>, Hrvoje Niksic wrote:

> Python has a little-known but very instructive method for determining the
> makeup of a float:
>
>>>> 1.1 .as_integer_ratio()

> (2476979795053773, 2251799813685248)

Only available in 2.6 or later. Are we already talking as though 2.5 doesnâ€™t
exist any more? I still have client machines running that (Debian Stable
5.0).

Lawrence D'Oliveiro, Nov 2, 2010
6. ### Hrvoje NiksicGuest

Ken Watford <> writes:

>>>>> 1.1 .as_integer_ratio()

>> (2476979795053773, 2251799813685248)

>
> Handy, but if you need the exact representation, my preference is
> float.hex, which seems to be the same as C99's %a format.

[...]
> Granted, it's not as easy for humans to interpret, but it's useful for
> certain things.

Since it's used by both C99 and Java, supporting it is a nice
interoperability feature:

In fact, the float output provides educational insight of its own
because it shows rounding effects without the apparent "garbage digits"
syndrome:

>>> 1.1 .hex()

'0x1.199999999999ap+0'

Here it is immediately obvious that the final digit of the infinite
sequence "1.1999..." is rounded from 9 to a. Printing the number with
any more digits would just reveal zeros, as expected.

Does anyone know why Python doesn't accept hex float literals in source
code?

Hrvoje Niksic, Nov 2, 2010
7. ### Terry ReedyGuest

On 11/2/2010 6:11 AM, Hrvoje Niksic wrote:

>>>> 1.1 .hex()

> '0x1.199999999999ap+0'
>
> Here it is immediately obvious that the final digit of the infinite
> sequence "1.1999..." is rounded from 9 to a. Printing the number with
> any more digits would just reveal zeros, as expected.
>
> Does anyone know why Python doesn't accept hex float literals in source
> code?

Assuming that the parser would have no problem with them:
1. the format is relatively recent
2. you can write float.fromhex('<hex literal>')
3. it never occurred to anyone to do so
4. literals are values supplied by the programmer; hex float values are
rare and when they do occur, they are usually the stored output of a
previous .hex() in Python or similar in other languages.
5. too easy to confuse in quick reading with normal float literals
6. the format is a bit weird and too esoteric for most programmers; they
should not be part of the basic syntax that everyone has to learn;
someone who reads float.fromhex(something) can look it up.

--
Terry Jan Reedy

Terry Reedy, Nov 2, 2010