Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:128564 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by lists.php.net (Postfix) with ESMTPS id A51C81A00BC for ; Tue, 26 Aug 2025 18:23:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1756232512; bh=EAJdWJuLzfSncPUVOW1kf2D4ukWNt/lXFwF9RVkfoK8=; h=Date:Subject:To:Cc:References:From:In-Reply-To:From; b=R4ra/e0hyYGhYDs4LuMYzvdWHSRMHtf5OWbFIdHYr6Y7E3HLw5Y7i1n6tngS4lnMs rT2l+YOqJvalXLhW5gq5PF4pTOLFMEnqLJJPTbpIdB2g9GIm7qoXk/5DoERDDRkbP8 mbulEPzVYaQaf2fEJwa3eKQRkNxB8fhFX66SZjiixa7mEhFT1BHJ1wglqZaHl/vWEd 9ZybXMC0XUxypyI192mMupKjM93uhcGibN/UAR6YitCwWV6YoUmR2uMxeH0dEoptnH XNxcFTqHYcnnLct+93RjAvqCHpwtHQIWo1Zi20r3BgB0M1A3BtD2EFS1ZgwH/lccZD BsBm+tYm97sag== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 0072518005D for ; Tue, 26 Aug 2025 18:21:52 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,SPF_HELO_NONE, SPF_PASS autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: No X-Envelope-From: Received: from chrono.xqk7.com (chrono.xqk7.com [176.9.45.72]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Tue, 26 Aug 2025 18:21:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bastelstu.be; s=mail20171119; t=1756232602; bh=dq3zqkIMaJBYW8fezvqcWiiM2DMVDJ88GqGhyyjgJSo=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type:from:to:cc:subject:message-id; b=JYA4t5zEqhLK0wxOXTMiZcKsCcv0LsosHVOpIhgIibvrWQHNtFDvLBZNuLoPIbfih Lmal7mFhkeBNkq9H3jVZ3rvQujU4tTnykZRsZEZ8tzlVip4x2uIjpej6W/0SRB0C78 PrZKv82CFOnqn+Cm8TiJ5MRWaG1QQYzsI/kgOCYTllnvnfYvsZlFQrziZPG35tdFzO JXb5PDL6/fIvwaCRUt/zAGcUizFInzgJgK1+LcAKbfVbCOZDwQT+SDy0Q0/wIhfoz/ hXpSJvNWFguME9ZoXY4igO/zR3DC/JoZxPC7Xn4vkkxlPaDTydoHADIPEDdPghmQt+ ODKWigz8Sg6DA== Message-ID: <499395ff-4ac9-4dc1-86fd-697b205467ba@bastelstu.be> Date: Tue, 26 Aug 2025 20:23:20 +0200 Precedence: list list-help: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 Subject: Re: [PHP-DEV] [RFC] Add "is_representable_as_float()" and "is_representable_as_int()" functions To: Alexandre Daubois Cc: PHP internals list References: Content-Language: en-US In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit From: tim@bastelstu.be (=?UTF-8?Q?Tim_D=C3=BCsterhus?=) Hi On 8/26/25 19:14, Alexandre Daubois wrote: >> 3.14 is not exactly representable as a IEEE-754 double-precision >> floating point number. The two nearest representable values are >> 3.14000000000000012434 (this one is the nearest) and >> 3.13999999999999968026. Returning `true` for >> `is_representable_as_float("3.14")` is therefore wrong to me. > > You're right about mathematical precision. Perhaps the function name > is misleading. What the function actually should check is whether a > string > float > string roundtrip preserves the value as PHP > developers would expect it, not whether it's mathematically exactly > representable in IEEE-754. > > Maybe a more accurate name would better reflect this behavior. Naming > is super hard again here. The goal is pragmatic: "will this value > survive a type conversion cycle without surprising changes?" "Surprising changes" is not a meaningful term. Keep in mind that the behavior of the function will need to be accurately documented and that folks need something to work with to determine whether a report is valid or not when bugs in the function get reported - which will inevitably happen. In fact to use one of the examples for the RFC: 1e10 does not roundtrip. php > var_dump((string)(float)"1e10"); string(11) "10000000000" "1e10" clearly is different than "10000000000". Generally speaking, I'm also not sure if “printing raw floats” is a use-case we should encourage. Instead almost any application will need to format a number for a specific use-case. Formatting numbers for human consumption [1] has different requirements compared to formatting numbers for programmatic consumption. Also note that the stringification of floats unfortunately is controlled by INI settings `precision` and `serialize_precision` which adds additional complexity. [1] My recommendation is using ext/intl's NumberFormatter: https://www.php.net/manual/en/class.numberformatter.php > need to communicate with JavaScript frontends, and knowing when a > numeric ID exceeds JavaScript's safe integer range would improve > interoperability. For *this* use case we would not need a complex function. A simple constant FLOAT_INTEGER_RANGE or similar would be sufficient. >> I also question how meaningful it is knowing that a given number is >> exactly representable as a float when (e.g. a power of two) when almost >> any operation on it will incur implicit rounding. > > To me, the code snippet in the RFC introduction illustrates a valid > use-case of a numeric identifier that could be dangerous to cast. Please note my remark regarding “strongly typed consumers”. Magically switching from JSON's number type to JSON's string type for specific values is needlessly increasing complexity for everyone who interacts with the JSON payload, particularly for compiled languages. If you know that the consumers of your JSON are having troubles with certain numbers you emit and you want to emit strings for those kind of numbers instead, then you should just emit strings all the time. In fact I'd argue that using JSON's number type for numeric IDs is wrong, just like treating phone numbers or zip codes as numbers is wrong. If it's not reasonable to do math on a value then it's likely not a number, but instead a numeric string. >> Long story short: What actual real-world problem does this RFC attempt >> to solve? The list in the “Introduction” section is not particularly >> meaningful with regard to the real world and the JSON example is wrong >> as outlined above. > > A few examples, as interoperability between with JSON/JavaScript is > the main point here, could be: > > - Snowflake IDs At the application boundary these should just be a string, since consumers of your API should treat IDs as opaque values, unless you want to give some guarantees (e.g. rough ordering, which would still work with strings). > - High-precision timestamps in microseconds Using a number is reasonable here, but see above regarding “magically switching types”. (From my experience timestamps are generally represented as ISO-8601 strings in JSON APIs anyways) > - Large auto-increment IDs in mature applications Same as snowflakes. > Hope I addressed your concerns. I'm afraid not. Best regards Tim Düsterhus