Live data from Hacker News

Python rounds float values by converting them to string and then back

github.com

141–150 of 152 posts

Re: Python rounds float values by converting them to string and then back

#141
This is where decimal floating point really shines. Since the exponential portion is base 10, it's trivially easy to round the mantissa.

The only silly part of ieee754 2008 is the fact that they specified two representations (DPD, championed by IBM, and BID, championed by Intel) with no way to tell them apart.

Re: Python rounds float values by converting them to string and then back

#142
post #134
post #14

Seems to be one of the best ways to go about it. From the comment in protobuf source (which does the same thing as Python), mentioned in the Twitter thread: (...) An arguably better strategy would be to use the algorithm described in "How to Print Floating-Point Numbers Accurately" by Steele & White, e.g. as implemented by David M. Gay's dtoa(). It turns out, however, that the following implementation is about as fas…

Yep, I'd be curious what any better alternative is. Consider that a float's internal representation is in base 2, and you're trying to round in base 10. Even if you didn't use a string, I'd assume you'd have to create an array of ints that contain base 10 digits in order to do the rounding, unless there are some weird math tricks that can be employed that can avoid you having to process all base 2 digits. And an arra…

In fact, I don't know what cdecimal now does but back when decimal.Decimal was pure python it would store the "decimal number" as a string and manipulate that.

Re: Python rounds float values by converting them to string and then back

#143
post #6

Apples libc used to shell-out to perl in a function: https://github.com/Apple-FOSS-Mirror/Libc/blob/2ca2ae7464771...

What if Perl uses libc ?????

That's not an issue unless perl calls wordexp (as part of the stuff it does when called by wordexp).

Re: Python rounds float values by converting them to string and then back

#144

Earlier quoted context omitted.

Fun fact: floor(x + 0.5) rounds 0.49999997 to 1.0 (this is 32 bit floats, the same principle applies to 64). Most libraries have slower than ideal round conversion because of historical dross; modern chips have a very fast SIMD round instruction but its behavior doesn't exactly match libc round. See https://github.com/rust-lang/rust/issues/55107 for a deeper discussion.

I just tried this on Python3 on a 64-bit x86 system: import math x = 0.49999999999999994 print(x-0.5) print(math.floor(x+0.5)) I got these printouts: -5.551115123125783e-17 1 So yes, something less than 1/2, with 1/2 added to it, has a floor of 1 in floating point math. Yet another reminder that floating point calculations are approximations , and not exact.

> Yet another reminder that floating point calculations are approximations, and not exact.

floating-point calculations are absolutely exact. What's not is conversions between decimals and floating-point.

Re: Python rounds float values by converting them to string and then back

#145

Earlier quoted context omitted.

I just tried this on Python3 on a 64-bit x86 system: import math x = 0.49999999999999994 print(x-0.5) print(math.floor(x+0.5)) I got these printouts: -5.551115123125783e-17 1 So yes, something less than 1/2, with 1/2 added to it, has a floor of 1 in floating point math. Yet another reminder that floating point calculations are approximations , and not exact.

> Yet another reminder that floating point calculations are approximations, and not exact. floating-point calculations are absolutely exact. What's not is conversions between decimals and floating-point.

> floating-point calculations are absolutely exact

Are you sure about that? What about 1.00000000000001^2 (using eg 64 bit double)?

Re: Python rounds float values by converting them to string and then back

#146
post #4

https://0.30000000000000004.com/

The worst way to explain something is to begin with "It's actually pretty simple."

I punched "It's actually pretty simple" into http://talktotransformer.com (which generates nonsense text from a seed using an OpenAI language model) and after a couple of tries it gave me this:

> It's actually pretty simple. We'll be looking at something called the "D-Wave P-500", which is a version of the P500 chip for quantum computers.

> It's basically a single bit computer, but with more than 500 qubits. Which means that our "real number" will have more numbers than the number of qubits that are available. That's really important.

> Quantum computers are theoretically able to do more things than just solve equations. For example, the way that a quantum computer uses energy from an electron to solve a classical math problem, or the way that it can break a complex calculation into smaller bits of information that each can solve on its own, is very different from how computers currently work.

> But I am not suggesting that a quantum computer can be used to solve more abstract problems. Because that would be crazy.

> But to give an example of what it could do, imagine doing a number crunching function that was 10× faster than a classical chip, and that had some really useful, and practical things that would be interesting to try.

Because Talk to Transformer is trained on real-world data, this supports the hypothesis that the phrase "It's actually pretty simple" is often followed by an unintelligible and highly technical explanation.

Re: Python rounds float values by converting them to string and then back

#147

In my experience there are few things slower that float to string and string to float. And it seems so unnecessary. I always implemented round to a specific digit based on the built-in roundss/roundsd functions which are native x86-64 assembler instructions (i.e. https://www.felixcloutier.com/x86/roundsd ). I do not understand why this would not be preferable to the string method. float round( float x, int digits, in…

float to string is incredibly fast now - look at Ulf Adams’ Ryu and Ryu Printf algorithms, which I’ve used to implement C++17 in Visual Studio 2019 (16.2 has everything implemented except general precision; the upcoming 16.4 release adds that). I don’t know of truly fast algorithms for string to float, although I improved upon our CRT’s performance by 40%.

Formatting is much faster than before, but still terribly slow compared to simply rounding numbers using math and floor and ceiling appropriately.

Ryu is more than 100x slower than something like

rval = floor(100*val+0.5)/100.0

(which is not quite right due to numerical issues, but close, and illustrates the idea).

Formatting, to get a rounded float, is terribly slow.

Re: Python rounds float values by converting them to string and then back

#148
post #93
post #85

Earlier quoted context omitted.

Why not have optimized versions that use native instructions when available, and then fall back to the portable version when they are not?

I'm unsure as to why they don't do that, I suspect it's because nobody using Python has found floating-point rounding to be a bottleneck yet.

It's because Python is slow everywhere, so it's hard to find bottlenecks like this. This method is easily 100x slower than need be. If everything else were well written, this would stand out. Since lots of Python is written like this, none stand out.

Death by 1000 papercuts....

Re: Python rounds float values by converting them to string and then back

#149

Earlier quoted context omitted.

I just tried this on Python3 on a 64-bit x86 system: import math x = 0.49999999999999994 print(x-0.5) print(math.floor(x+0.5)) I got these printouts: -5.551115123125783e-17 1 So yes, something less than 1/2, with 1/2 added to it, has a floor of 1 in floating point math. Yet another reminder that floating point calculations are approximations , and not exact.

> Yet another reminder that floating point calculations are approximations, and not exact. floating-point calculations are absolutely exact. What's not is conversions between decimals and floating-point.

Their not being exact is why 0.49999997 + 0.5 = 1. There isn't enough precision in the range just below 1.0 to represent the number 0.99999997.

Re: Python rounds float values by converting them to string and then back

#150
post #145

Earlier quoted context omitted.

> Yet another reminder that floating point calculations are approximations, and not exact. floating-point calculations are absolutely exact. What's not is conversions between decimals and floating-point.

> floating-point calculations are absolutely exact Are you sure about that? What about 1.00000000000001^2 (using eg 64 bit double)?

Maybe the parent wanted to say that the result is detetministic and not far too off from the true value (in fact, as accurate as possible given the format). In the other words FP is exact but abides by a slight different calculation rule involving rounding.
Post reply on HN