Hi Stas,
Stanislav Malyshev wrote:
Hi!
foot, by discarding possibly important information when serialising - an
operation that's supposed to perfectly reproduce a value!
I'm not sure this is correct. Also, for values that are not exactly
representable in binary, I'm not sure you want to see
0.1000000000000000055511151231257827021181583404541015625 instead of
0.1.
This assumes we would print an exact decimal representation, but that's
far more than necessary. In order to get the same result when converted
back to a float, we need at most 17 digits. In many cases we don't even
need to show 17, because there are not that many digits in a
full-precision decimal representation (e.g. 0.5). We could use less in
many cases if PHP were to switch to the approach other languages use,
where we output only the shortest sequence of digits producing the same
value when converted back to a float (whereas currently we output in
full precision, up to 17 significant figures).
You certainly don't want var_dump to print that by default - this
would make display cluttred and have very high WTF factor
Why would displaying at most three extra digits have a "high WTF factor"?
- why I
entered 0.1 and get this enormous snake of a number?
PHP must be broken!
var_dump() is a debugging function. If it shows a value, it must
represent it accurately. Otherwise:
$ php -r 'var_dump(1.00000000000002, 1.00000000000001, 1.00000000000001
=== 1.00000000000002);'
float(1)
float(1)
bool(true)
Please explain to me why this is intuitive and reasonable behaviour for
a debugging function.
Furthermore, if PHP developers find floating-point confusing and are
genuinely surprised that 0.1 cannot be represented in binary exactly,
then perhaps they should go and learn about what floating-point numbers
do, rather than naïvely continuing on thinking they're decimals thanks
to PHP lying to them! It is not the job of the language to try and hide
that floats are imprecise from programmers.
Moreover, when you do "$a = 8.2 - 0.2" and then print/send $a, do you
want to see 8 or 7.99999999999999911182158029987476766109466552734375?
Let's look at what our contemporary programming languages do.
Python:
>>> 8.2 - 0.2
7.999999999999999
JavaScript:
8.2 - 0.2
7.999999999999999
That's much shorter than your suggestion.
Heck, let's look at what var_export() does:
$ php -r 'var_export(8.2 - 0.2);'
7.9999999999999991
Still a lot shorter.
In fact, when we represent 0.1 as 0.1 when serializing our outputting,
But we don't represent 0.1 as 0.1:
$ php -r 'var_export(0.1);'
0.10000000000000001
we are not discarding information, on the contrary - we are preserving
exactly the information that was given to us by user.
$ php -r 'var_dump(1.00000000000002);'
float(1)
That doesn't look very preserved to me.
print floats to their full precision - including in var_dump(). This can
create unreasonable confusion when debugging (why are two numbers that
appear identical with var_dump() reported as inequal?), means
You really think that displaying 8.2 - 0.2 as 8 is more confusing than
displaying it as 7.99999999999999911182158029987476766109466552734375?
It's more *honest*. If two values are different, they should not be
displayed the same.
And, again, the result would not be that large:
$ php -r 'var_export(8.2 - 0.2);'
7.9999999999999991
potentially important information is removed by default, and really
ought not to be a global setting anyway: if you want to format your
numbers with reduced precision, do so explicitly.
That would mean optimizing for case that nobody wants, and de-optimizing
case that pretty much everybody wants.
Who wants to round numbers to the same precision in all situations, for
all apps running on their server, for all code running within a given
request, even in libraries?
Ask 100 people using PHP what
they want as a result of 8.2 - 0.2 and count how many of them want to
see full-precision monster of a number.
"7.9999999999999991" isn't that monstrous, and it could be even less so
if PHP used a nicer float-to-string conversion approach.
There might be others worth dealing with, too, these are just the first
three I thought of.
I would very much advise not to mess with any options until we are
definitely, 100%, without any doubt sure that nobody needs to use it for
anything. Removing options earns us nothing in terms of functionality.
If nobody uses them - ok, fine - drop them. If we need to remove them
e.g. because component they address goes away or changes function in a
way that makes it irrelevent - fine, drop them. But doing it just
because very small number of people that we can engage in discussion on
the list (and that's not going to ever change - PHP user community is
vastly larger than people even reading this list, let alone actively
participating in it) think it's not needed IMHO is a very wrong
approach.
This might be a fine argument, but I'm not arguing these settings are
not needed. I'm arguing they're actively harmful.
--
Andrea Faulds
https://ajf.me/
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php