psl icon indicating copy to clipboard operation
psl copied to clipboard

[Type] Coerce float to string

Open veewee opened this issue 5 years ago • 6 comments

Currently, it is not possible to convert a float -> string. https://github.com/azjezz/psl/blob/c34f75bcb27298a1fdb017c07cd90f07c78046e2/src/Psl/Type/Internal/StringType.php#L39

The other way around (string -> float) is possible.

We could go for one of these solutions to make it possible in a locale-safe way:

  • https://github.com/moneyphp/money/blob/512333ef834bd77f76e865a30eb5963d480e2ed7/src/Number.php#L64-L71
  • https://github.com/brick/math/blob/49d9d6d83d9f97ebc6e8f3d7a4adbc7cd649afc2/src/BigNumber.php#L165-L175

Would it make sense to add it and do you see any additional risks?

veewee avatar Feb 26 '21 06:02 veewee

I think this got fixed in PHP 8.0 right? There casting a float to string is no longer locale aware.

BackEndTea avatar Feb 26 '21 07:02 BackEndTea

Yes it did: https://wiki.php.net/rfc/locale_independent_float_to_string

But PSL1 also supports PHP 74.

So it's probably best to go for something like

sprintf('%.14F', $number)

But that means we need to specify a precision - which can be seen as a data manipulation. Because it results in:

>>> sprintf('%.14F', 3.132)
=> "3.13200000000000"

We could rtrim 0 from the fractional part or leave it as-is : it doesn't hurt anyone as long as the number is >= max([0, ini_get('precision')])

veewee avatar Feb 26 '21 07:02 veewee

we are talking about string -> float here, not float -> string, right?

azjezz avatar Feb 28 '21 15:02 azjezz

Sorry for the confusion. I updated the issue. It's about coercing a float -> string. See https://github.com/azjezz/psl/blob/c34f75bcb27298a1fdb017c07cd90f07c78046e2/src/Psl/Type/Internal/StringType.php#L39

veewee avatar Feb 28 '21 17:02 veewee

@veewee are you interested in writing a PR for this?

i guess we can go with something like:

$str = Str\trim_right(Str\format('%.14F', $value), '0');
if (Str\ends_with($str, '.')) {
 $str .= '0';
}

return $str;

see https://github.com/azjezz/psl/blob/1.5.x/src/Psl/Type/Internal/LiteralScalarType.php#L135-L143

azjezz avatar Mar 15 '21 02:03 azjezz

Sure, I'll give it a try later this week.

veewee avatar Mar 15 '21 07:03 veewee

I moved around this by using numeric_string()->coerce($float) instead. Seems sufficient to me.

veewee avatar Apr 04 '24 10:04 veewee