On Tue, Dec 12, 2023 at 2:04 PM G. P. B. <george.bany...@gmail.com> wrote:
>
> On Fri, 8 Dec 2023 at 10:14, Alexander Pravdin <alex.prav...@interi.co>
> wrote:
>
> > On Thu, Dec 7, 2023 at 11:36 PM G. P. B. <george.bany...@gmail.com> wrote:
> >
> > - Objects are always casted to true, GMP(0) will equal to true.
> >>>
> >>
> >> This is incorrect, GMP object do _not_ support casts to bool
> >> See https://3v4l.org/LHpD1
> >>
> >
> > This is weird. Any PHP user would expect that a zero number can be easily
> > casted to boolean false. This is also why I think we need a scalar decimal
> > type.
> >
>
> Internal objects can overload casts, SimpleXML overloads the boolean cast
> already.
> We could add this to GMP to return false for 0.
>
>
> > It works the same as "float" in terms of its usage and type casting except
> >>> for one thing. Float value can be passed to a decimal argument or
> >>> typecasted with a warning like "Float to decimal conversion may incur
> >>> unexpected results".
> >>>
> >>> Decimal to float conversion is allowed and smooth:
> >>>
> >>> function f (float $value) {}
> >>>
> >>> f(0.2);
> >>>
> >>> f(0.2d); // allowed with no warnings
> >>>
> >>
> >> I disagree with this part, floats can not represent decimal values
> >> properly e.g.
> >> $f1 = 0.1;
> >> $f2 = 0.2;
> >> $f3 = 0.3;
> >> var_dump($f1 + $f2 === $f3);
> >>
> > will return false.
> >> As such, floats are not at all compatible with decimals.
> >>
> >
> > Yes, I know that. I mentioned that we can not convert float to decimal
> > without an intermediate value where we apply rounding and get a
> > human-readable value in some representation (string or whatsoever).
> >
> > My intention was to provide implicit conversion with warnings because I
> > guess that the majority of end users will expect that numeric scalar types
> > are interoperable. To not make them scared and point them to issues in
> > their code instead of slapping their hands immediately when they run
> > something that is not so correct.
> >
> >
> >
> >> Moreover, the whole point of adding a warning when implicit conversions
> >> from int to float happen was to be able to warn before elevating the
> >> warning to a TypeError.
> >>
> >
> > Sorry, I'm not aware of issues of converting ints to floats. Are there any
> > issues? I understand the issue of the backward conversion, but not the
> > forward one. Could you add details here?
> >
>
> I meant converting floats to int.
> But you can lose precision when converting an integer to float as there are
> only 53 bits for the coefficient.
>
>
> > Therefore, introducing behaviour that warns instead of throwing a
> >> TypeError is already a no-go from my PoV.
> >>
> >
> > I'm okay with TypeErrors for float to decimal conversions as well. This is
> > not a key point of my proposal. If the community prefers errors instead of
> > warnings - that's also fine.
> >
> >
> > Literal numbers in the code are converted to floats by default. If
> >>> prepended by the "(decimal)" typecast, the decimal result is produced
> >>> without an intermediary float.
> >>>
> >>
> >> This behaviour is rather suboptimal, I'd rather have literals be decimals,
> >> as decimals to floats should always be a reasonable implicit coercion
> >> considering we already do int to float.
> >>
> >
> > Is it optimal to perform conversions on every fractional literal? This is
> > also not a key point for me and I'm okay with any implementation that the
> > internals community prefers.
> >
> >
> >
> >>  New declare directive "default_decimal" is added. When used, literals and
> >>
> >>> math operations return decimal by default instead of float. This is to
> >>> simplify creating source files working with decimals only.
> >>>
> >>
> >> Please no, no new declare directives that affect engine behaviour.
> >> Strict types was already a mistake because of this IMHO.
> >>
> >
> > I didn't know that the strict types directive was a mistake. My intention
> > is to be able to write clean all-decimal units of code and not break the
> > backward compatibility. The old code should work as it was before. At the
> > same time, there are use cases when the whole class/project should be
> > written with decimals only. As a user, I want to do that without complex
> > language structures and excessive typehints or explicit conversions. The
> > all-decimal code  should be as clean as it is now with floats. This is why
> > I proposed this directive. Can you suggest something better to achieve the
> > same?
> >
>
> The issue is that I don't think having arbitrary precision decimals as a
> core language feature is a necessity compared to rational types.
> A cast from rational to float wouldn't produce a large round trip, whereas
> trying to figure out arbitrary precision is more difficult.
> But in any case, having a declare/INI or whatever that changes the
> behaviour of the engine/language is not a good design choice.
>
>
> > [...]
> >
> >  The new type uses libmpdec internally to perform decimal calculations
> >> (same
> >>
> >>> as Python).
> >>>
> >>
> >> I really don't think we need arbitrary precision decimals.
> >>
> > I'm also not convinced using a floating point spec is the most sensible,
> >> due to the rounding errors this is going to introduce.
> >> The non-arbitrary IEEE 754-2008 specification cannot describe the decimal
> >> 123457.1467 exactly, which is frankly pointless.
> >>
> >> Decimals, or more broadly rational numbers that, outside numerical
> >> computations, that are going to be used are not going to need huge
> >> denominators.
> >>
> >> I've been thinking about this for a while, and I personally think that
> >> rational numbers are just better than trying to support only decimals.
> >> And considering we have 64 bits to play with for a new zval type
> >> splitting the bits into a 32-bit unsigned integer for the numerator and an
> >> 32-bit signed integer for the denominator should provide us with enough
> >> reasonable rational numbers.
> >> As any number that do not fit in this structure seems to be something
> >> relegated to the world of numerical computation where floats are what are
> >> mostly used anyway.
> >>
> >
> > If you can suggest a better way of working with fractional numbers -
> > please do :) But IMO limiting the language by 64 bits is not a good way. It
> > is more easy to go over the limit than you may think :) Especially in some
> > intermediary values while performing complex calculations. I could be
> > wrong, but fractional numbers limited to 64 bits sound like a bandaid. The
> > language will tell users "hey, you can do something general, but if you
> > want something else please don't use me at all or involve bandaids with
> > extensions". My key point is not only to allow working with decimals, but
> > also to make all the alternatives useless, cover their functionality by
> > builtin tools, to free users from thinking about workarounds and bandaids.
> > From my POV, introducing a new decimal type that does not cover the
> > GMP/bcmath/ext-decimal functionality is pointless and a waste of time.
> >
>
> Again, the use cases for arbitrary precision numbers seems rather limited,
> and having this as an extension does not seem problematic at all.
> My current issue is that there is no way to represent "small" numbers such
> as 0.1 or 5.8 exactly.
> Arbitrary precision is a totally different ballpark, be that for integers
> and/or fractional values and makes everything slow, just look at Python who
> is *finally* investing time and money to make the most common numbers
> (those that fit in a machine word) not be abysmally slow.
>
>
> > [...]
> >
>
>
>
> > How quickly you would be able to read something like this:
> > gmp_add(gmp_mul(gmp_div(gmp_sub($value, $add), $value2, $factor,
> > gmp_sin($value3), gmp_intval($value))) ?
> >
> This absence of intuitive readability makes the development and support
> > difficult and it's better to choose another language. This is what I want
> > to change and make PHP powerful enough for this kind of applications.
> >
>
> GMP supports operator overloading, so you do not need to write this, and as
> far as I see, ext/decimal *also* supports operator overloading so you can
> just write it using the normal arithmetic operations.
> Moreover, it supports type casts so you can just do (int) $GMP instead of
> gmp_intval($GMP);
> And it also supports using the comparisons operatos on it instead of using
> gmp_cmp()
>
> The only thing that is, currently, not possible to do is a cast _to_ GMP
> using (GMP), but maybe that's something that could be added to the engine
> for internal objects, but I'm not sure about this.
>
> It seems, your main motivation to have this as a language feature is to
> have access to operator overloading and casting behaviour, that internal
> objects already support.
> Which diminish the cost/benefit of making the engine changes, especially if
> the default behaviour doesn't change and one needs to maintain effectively
> two different versions of PHP depending on if it is in "decimal" or
> "floating" mode, which raises a plethora of questions just in its own.
>
> Best regards,
>
> Gina P. Banyard

Hey Gina,

> GMP supports operator overloading

GMP kinda-sorta-most-of-the-time supports operator overloading.
Sometimes ... it doesn't. I implemented a field library in PHP (for
work a couple of years ago) and occasionally, overloading would cast
things back to float/int and break the math. I don't have access to
that code, so I don't have any examples readily available (and the
fact that an extension can do overloading but we can't in user-land is
a whole different can of worms which made this library ridiculously
hard to work with -- we rewrote everything in Scala and never looked
back). Needless to say, if I were to go into a project that required
GMP, I wouldn't trust the overloading.

Just my 2¢

Robert Landers
Software Engineer
Utrecht NL

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php

Reply via email to