Live data from Hacker News

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

github.com

31–40 of 152 posts

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

#31
post #19
post #3

I dunno, how efficient is this?

Compared to base=10^places, multiply, truncate, divide? Horriby inefficient.

Sure, but their approach is on the other hand more correct. All numerical code reaches a point where you have to balance performance vs. correctness, and here cpython has chosen correctness over speed.

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

#32
post #15
post #4

https://0.30000000000000004.com/

Computers can only natively store integers, so they need some way of representing decimal numbers. Really? How do computers "natively" store integers?

The intent of that sentence is a lot clearer if you also consider the subsequent text, which expands on the idea quite a bit:

> Computers can only natively store integers, so they need some way of representing decimal numbers. This representation comes with some degree of inaccuracy. . . Why does this happen? It's actually pretty simple. When you have a base 10 system (like ours), it can only express fractions that use a prime factor of the base. . .

Perhaps a more formally correct way to put it is that integers (and natural numbers) are the only numbers that a computer can manage in a way that behaves reasonably similarly to the corresponding mathematic set. Specifically, as long as you stick to their numeric range, computer ints behave like a group, just like real integers do. But IEEE floats break the definition of a field in every which way, so they're really not a great match for the rationals.

That said, you could represent the rationals as a pair of integers, and that would be better-behaved, and some programming languages do do that. But I'm not aware of an ISA that supports it directly.

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

#33
post #4

https://0.30000000000000004.com/

Somewhat offtopic, but is there a reason some many explanations of this issue lump together the fundamental principle of how numbers are represented (integers vs. fractions vs. exact reals (technically impossible) vs. IEEE 754) and the base (decimal vs. binary)? Every time I read something like the explanation on that site, I wonder if I would understand it if I didn't knew it already.

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

#34
post #22
post #15

Earlier quoted context omitted.

Computers can only natively store integers, so they need some way of representing decimal numbers. Really? How do computers "natively" store integers?

It seems to just be layman shorthand for storing (not huge) integers as binary isn't lossy.

Storing integers as decimal (which computers can do easily) isn't lossy either.

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

#35
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, int base) { float factor = pow( base, digits ); return roundss( x * factor ) / factor; }

I guess this has the effect of not working for numbers near the edge of it's range.

One could check this and fall back to the string method. Or alternatively use higher precision doubles internally:

float round( float x, int digits, int base ) { double factor = pow( base, digits ); return (float)( roundsd( x * factor ) / factor ); }

But then what do you do if you have a double rounded and want to maintain all precision? I think there is likely some way to do that by somehow unpacking the double into a manual mantissa and exponent each of which are doubles and doing this manually - or maybe using some type of float128 library (https://www.boost.org/doc/libs/1_63_0/libs/multiprecision/do...)...

But changing this implementation now could cause slight differences and if someone was rounding then hashing this type of changes could be horrible if not behind some type of opt-in.

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

#37
post #27
post #11

Earlier quoted context omitted.

So efficient that nobody really cared about or mentioned it all those decades, so there's that...

It's Python, it's not like anybody is going to complain about performance, because nobody expects any.

Many people complain about performance, and enormous amounts of effort have been spent on improving it, successfully. People do expect good performance, and can achieve it in many useful cases.

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

#39
post #17
post #5

Maybe I'm missing something but what's wrong with rounding floats this way?

Rounding a number is, in the common case, multiplying it by some base, truncating to an integer, and dividing by the base. You do have to handle extremely high exponents, but even the logic for that is not complex. Example of implementing it the sane way: https://github.com/numpy/numpy/blob/75ea05fc0af60c685e6c071d... Every step of this function is complex and expensive, especially printing a float as a decimal is ve…

How does truncating a positive number ever round up?
Post reply on HN