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]