Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:128238 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 43BEC1A00BC for ; Sat, 26 Jul 2025 13:45:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1753537425; bh=Kep/BomIiENRJPPELi4olcBhP/C37XMuRX+RaKASe2o=; h=Date:Subject:To:References:From:In-Reply-To:From; b=d3bzLI41rkOl+8PuT/cj+nPILAscSKGGXwsiU6YiZ3unrQZBdYky7EfftN9DQbK8H clc5/A7/p5kGjbyq29jM4erPIk7aRfU+o80jV0b7zyUhaWgObhH1Am/1YIrFSMIOZO qQlqb7MyEX9S2jJ64nOIPeymXuFnkCXsUqDoWPxTiHc+cSSNooNArj0KeEA1ZD0rqG y0A4vUaFZtORqficawAPGUTm+nBFvMlBuPTWyy3uSG8Pteo37gnhPiijYWtpk7BLrs ZKBg00Q5q2w2Z+l2iwOjDQdCoHiPxJc/RtlCS1H5/a1NFmw3fqQJ9kV3BZddHXlhkI lC37T7hzNeXcA== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 2CDA718006C for ; Sat, 26 Jul 2025 13:43:44 +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.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_MISSING,HTML_MESSAGE, RCVD_IN_DNSWL_LOW,SPF_HELO_PASS,SPF_PASS autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: Error (Cannot connect to unix socket '/var/run/clamav/clamd.ctl': connect: Connection refused) X-Envelope-From: Received: from fhigh-b7-smtp.messagingengine.com (fhigh-b7-smtp.messagingengine.com [202.12.124.158]) (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 ; Sat, 26 Jul 2025 13:43:43 +0000 (UTC) Received: from phl-compute-06.internal (phl-compute-06.phl.internal [10.202.2.46]) by mailfhigh.stl.internal (Postfix) with ESMTP id 153987A0D6D for ; Sat, 26 Jul 2025 09:45:27 -0400 (EDT) Received: from phl-mailfrontend-02 ([10.202.2.163]) by phl-compute-06.internal (MEProxy); Sat, 26 Jul 2025 09:45:27 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rwec.co.uk; h=cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm3; t=1753537526; x=1753623926; bh=yvxhD0ViMk oLqDTCE+V53mmy8Ks4iOkiLQnUSw7LcZ0=; b=dp/t7qSBdY3iqpU4mo3lOY5XRM 4KvN9+4mZGBSHe0/4iI7EX2ssK/ViQg1nFkoM3P97JhyRHW34LW8WyG4f3k6y3g2 kBcVlz25mUEl0/O1V+cEAdtiZBnVgLs0kQ8Ig6rCybLstz17FFDUCiRb0YDvK3bn s828XvQyXNHopvwwzx6gozSzx027QxfjeJxhskcFFO8mGm5yVm7qOo+rwYutRWFI 93EZ7EjGN64RFTOtqCHTY070/qVkPVl4lA2SFE2nVubPyIUoZeTp5KpdxrebpwRd OMVW0E2UzbC5dBpN5axeXgAAl9eUAX2pUW72n7zyy9eYs4YYuFgcKgCsf2xQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm3; t= 1753537526; x=1753623926; bh=yvxhD0ViMkoLqDTCE+V53mmy8Ks4iOkiLQn USw7LcZ0=; b=d3WBmW4ejeucrqjqTdnQKyNaGq6J7C1GfVpIQ3458JWMJ65bvaN R3dIL+4Za9Kql9LwiuFq+S065AEsvmy8exMluzKmOo+YAOdY/0+ahNPacLb8HDiu NhG+Pr3sErzNCYsnK4kBbBf0UcfLD8oyZJaEEM4AQ/R4rKybAqjzcJOvowW3rJWe VgEUmcx0eul5aEPMlQESVpIOqLzMMYmPcA132A2Js3FM4/veUZ1ztqzoVs/QY+eI WRcz7fESAHx55GVqUnvpqjhjrB8ylOqXmcnt/csKYERHWHzgfLeZDjybHC2PyCT/ D2G1WBc68P4SakzlWDP5qMuejcI8Wn+6ZyQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeffedrtdefgdekieehjecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpuffrtefokffrpgfnqfghnecuuegr ihhlohhuthemuceftddtnecunecujfgurheptgfkffggfgfuvfhfhfgjsegrtderredtvd ejnecuhfhrohhmpedftfhofigrnhcuvfhomhhmihhnshculgfkoffuohfrngdfuceoihhm shhophdrphhhphesrhifvggtrdgtohdruhhkqeenucggtffrrghtthgvrhhnpeehteelie eigfeuudeiueeiffdvveehudeufeekjeeugffffedtiedtgeettdelteenucevlhhushht vghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehimhhsohhprdhphhhpse hrfigvtgdrtghordhukhdpnhgspghrtghpthhtohepuddpmhhouggvpehsmhhtphhouhht pdhrtghpthhtohepihhnthgvrhhnrghlsheslhhishhtshdrphhhphdrnhgvth X-ME-Proxy: Feedback-ID: id5114917:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA for ; Sat, 26 Jul 2025 09:45:26 -0400 (EDT) Content-Type: multipart/alternative; boundary="------------k8qhrx0aYbEWhHD11v0EWLVP" Message-ID: Date: Sat, 26 Jul 2025 14:45:24 +0100 Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PHP-DEV] [DISCUSSION] Adding the "is_integer_safe()" function To: internals@lists.php.net References: Content-Language: en-GB In-Reply-To: From: imsop.php@rwec.co.uk ("Rowan Tommins [IMSoP]") This is a multi-part message in MIME format. --------------k8qhrx0aYbEWhHD11v0EWLVP Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit On 26/07/2025 07:13, Alexandre Daubois wrote: > The idea is to have a function that receives an integer or a float and > returns bool if the provided argument is inside the safe Javascript > integer interval, namely [-(2^53)+1 ; (2^53)-1]. That suggests maybe the name should communicate "safe for JavaScript"; or more generally "safe for 64-bit IEEE floating point". is_safe_for_js() is_safe_for_float() > It's signature would > be `is_integer_safe(int|float $num): bool`. I'm not sure if accepting floats in the same function makes sense. If the question is "can this value safely be stored in a float?" and you give it a float, then the answer is surely "yes". You have no way of knowing if it _already_ lost precision during a previous operation. Possibly there could be a separate function which asks "can this float value be safely converted to an integer?", but that implies a different definition - it wouldn't make much sense to answer "yes" for 3.5, or NaN. That then makes me wonder if this is really part of a family of functions relating to casts - something I've been thinking about off an on for some time. Namely, "can this value be losslessly converted to this type?" My thinking is that this needs new syntax, to avoid dozens of specific functions. For instance, a generic (or generic-like) form: function can_lossless_cast(mixed $value): bool can_lossless_cast(2 ** 50) === true can_lossless_cast(2 ** 54) === false can_lossless_cast(2 .0** 54) === true can_lossless_cast(2.0 ** 65) === false can_lossless_cast(3.5) === false can_lossless_cast(NaN) === false can_lossless_cast('9007199254740991000') == true // less than 2**64 can_lossless_cast('9007199254740991000') == false // more than 2**53 can_lossless_cast('9007199254740991000') == true can_lossless_cast('3.5') == true Regards, -- Rowan Tommins [IMSoP] --------------k8qhrx0aYbEWhHD11v0EWLVP Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 8bit
On 26/07/2025 07:13, Alexandre Daubois wrote:

The idea is to have a function that receives an integer or a float and
returns bool if the provided argument is inside the safe Javascript
integer interval, namely [-(2^53)+1 ; (2^53)-1].

That suggests maybe the name should communicate "safe for JavaScript"; or more generally "safe for 64-bit IEEE floating point".

is_safe_for_js()
is_safe_for_float()


It's signature would
be `is_integer_safe(int|float $num): bool`.


I'm not sure if accepting floats in the same function makes sense. If the question is "can this value safely be stored in a float?" and you give it a float, then the answer is surely "yes". You have no way of knowing if it _already_ lost precision during a previous operation.

Possibly there could be a separate function which asks "can this float value be safely converted to an integer?", but that implies a different definition - it wouldn't make much sense to answer "yes" for 3.5, or NaN.


That then makes me wonder if this is really part of a family of functions relating to casts - something I've been thinking about off an on for some time. Namely, "can this value be losslessly converted to this type?"

My thinking is that this needs new syntax, to avoid dozens of specific functions. For instance, a generic (or generic-like) form:

function can_lossless_cast<T>(mixed $value): bool

can_lossless_cast<float>(2 ** 50) === true
can_lossless_cast<float>(2 ** 54) === false

can_lossless_cast<int>(2 .0** 54) === true
can_lossless_cast<int>(2.0 ** 65) === false
can_lossless_cast<int>(3.5) === false
can_lossless_cast<int>(NaN) === false

can_lossless_cast<int>('9007199254740991000') == true // less than 2**64
can_lossless_cast<float>('9007199254740991000') == false // more than 2**53

can_lossless_cast<int|float>('9007199254740991000') == true
can_lossless_cast<int|float>('3.5') == true


Regards,

-- 
Rowan Tommins
[IMSoP]
--------------k8qhrx0aYbEWhHD11v0EWLVP--