Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #100991 > unrolled thread
| Started by | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| First post | 2015-12-31 00:18 +1100 |
| Last post | 2015-12-30 09:35 -0500 |
| Articles | 3 — 3 participants |
Back to article view | Back to comp.lang.python
Is it safe to assume floats always have a 53-bit mantissa? Steven D'Aprano <steve@pearwood.info> - 2015-12-31 00:18 +1100
Re: Is it safe to assume floats always have a 53-bit mantissa? Marko Rauhamaa <marko@pacujo.net> - 2015-12-30 16:19 +0200
Re: Is it safe to assume floats always have a 53-bit mantissa? Terry Reedy <tjreedy@udel.edu> - 2015-12-30 09:35 -0500
| From | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| Date | 2015-12-31 00:18 +1100 |
| Subject | Is it safe to assume floats always have a 53-bit mantissa? |
| Message-ID | <5683d9aa$0$1618$c3e8da3$5496439d@news.astraweb.com> |
We know that Python floats are equivalent to C doubles, which are 64-bit
IEEE-754 floating point numbers.
Well, actually, C doubles are not strictly defined. The only promise the C
standard makes is that double is no smaller than float. (That's C float,
not Python float.) And of course, not all Python implementations use C.
Nevertheless, it's well known (in the sense that "everybody knows") that
Python floats are equivalent to C 64-bit IEEE-754 doubles. How safe is that
assumption?
I have a function with two implementations: a fast implementation that
converts an int to a float, does some processing, then converts it back to
int. That works fine so long as the int can be represented exactly as a
float.
The other implementation uses integer maths only, and is much slower but
exact.
As an optimization, I want to write:
def func(n):
if n <= 2**53:
# use the floating point fast implementation
else:
# fall back on the slower, but exact, int algorithm
(The optimization makes a real difference: for large n, the float version is
about 500 times faster.)
But I wonder whether I need to write this instead?
def func(n):
if n <= 2**sys.float_info.mant_dig:
# ...float
else:
# ...int
I don't suppose it really makes any difference performance-wise, but I can't
help but wonder if it is really necessary. If sys.float_info.mant_dig is
guaranteed to always be 53, why not just write 53?
--
Steven
[toc] | [next] | [standalone]
| From | Marko Rauhamaa <marko@pacujo.net> |
|---|---|
| Date | 2015-12-30 16:19 +0200 |
| Message-ID | <87h9j03tot.fsf@elektro.pacujo.net> |
| In reply to | #100991 |
Steven D'Aprano <steve@pearwood.info>: > Nevertheless, it's well known (in the sense that "everybody knows") > that Python floats are equivalent to C 64-bit IEEE-754 doubles. How > safe is that assumption? You'd need to have it in writing, wouldn't you? The only spec I know of promises no such thing: Floating point numbers are usually implemented using double in C; information about the precision and internal representation of floating point numbers for the machine on which your program is running is available in sys.float_info. <URL: https://docs.python.org/3/library/stdtypes.html#typesnumeric> > As an optimization, I want to write: > > def func(n): > if n <= 2**53: > # use the floating point fast implementation > else: > # fall back on the slower, but exact, int algorithm > > [...] > > But I wonder whether I need to write this instead? > > def func(n): > if n <= 2**sys.float_info.mant_dig: > # ...float > else: > # ...int > > I don't suppose it really makes any difference performance-wise, but I > can't help but wonder if it is really necessary. If > sys.float_info.mant_dig is guaranteed to always be 53, why not just > write 53? Mainly because 2**sys.float_info.mant_dig looks much better than 2**53 Marko
[toc] | [prev] | [next] | [standalone]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2015-12-30 09:35 -0500 |
| Message-ID | <mailman.75.1451486141.11925.python-list@python.org> |
| In reply to | #100991 |
On 12/30/2015 8:18 AM, Steven D'Aprano wrote:
> We know that Python floats are equivalent to C doubles,
Yes
> which are 64-bit IEEE-754 floating point numbers.
I believe that this was not true on all systems when Python was first
released. Not all 64-bit floats divided them the same way. I believe
there has been some discussion on pydev whether the python code itself
should assume IEEE now. I do not believe that there are currently any
buildbots that are not IEEE. Does the standard allow exposing the 80
bit floats of FP processors?
> Well, actually, C doubles are not strictly defined. The only promise the C
> standard makes is that double is no smaller than float. (That's C float,
> not Python float.) And of course, not all Python implementations use C.
>
> Nevertheless, it's well known (in the sense that "everybody knows") that
> Python floats are equivalent to C 64-bit IEEE-754 doubles. How safe is that
> assumption?
>
> I have a function with two implementations: a fast implementation that
> converts an int to a float, does some processing, then converts it back to
> int. That works fine so long as the int can be represented exactly as a
> float.
>
> The other implementation uses integer maths only, and is much slower but
> exact.
>
> As an optimization, I want to write:
>
>
> def func(n):
> if n <= 2**53:
The magic number 53 should be explained in the code.
> # use the floating point fast implementation
> else:
> # fall back on the slower, but exact, int algorithm
>
>
> (The optimization makes a real difference: for large n, the float version is
> about 500 times faster.)
>
> But I wonder whether I need to write this instead?
>
> def func(n):
> if n <= 2**sys.float_info.mant_dig:
> # ...float
> else:
> # ...int
Pull the calculation of the constant out of the function. Naming the
constant documents it and allows easy change. There is pretty standard
in scientific computing (or was once).
finmax = 2 ** sys.float_info.mant_dig # -1?
def func(n):
if n <= finmax:
...
--
Terry Jan Reedy
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web