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]

Reply via email to