mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 20:47:45 +00:00
LibJS: Support modulo(x, y) with different types
It's a bit annoying having to add '.0' to y given that it's an integral number in most cases. This turns the single template parameter T into T and U to permit that.
This commit is contained in:
parent
1ec917aa23
commit
9c209b8079
5 changed files with 15 additions and 14 deletions
|
@ -77,12 +77,13 @@ ThrowCompletionOr<T*> ordinary_create_from_constructor(GlobalObject& global_obje
|
||||||
}
|
}
|
||||||
|
|
||||||
// x modulo y, https://tc39.es/ecma262/#eqn-modulo
|
// x modulo y, https://tc39.es/ecma262/#eqn-modulo
|
||||||
template<typename T>
|
template<typename T, typename U>
|
||||||
T modulo(T x, T y)
|
auto modulo(T x, U y) requires(IsArithmetic<T>, IsArithmetic<U>)
|
||||||
{
|
{
|
||||||
// The notation “x modulo y” (y must be finite and non-zero) computes a value k of the same sign as y (or zero) such that abs(k) < abs(y) and x - k = q × y for some integer q.
|
// The notation “x modulo y” (y must be finite and non-zero) computes a value k of the same sign as y (or zero) such that abs(k) < abs(y) and x - k = q × y for some integer q.
|
||||||
VERIFY(y != 0);
|
VERIFY(y != 0);
|
||||||
if constexpr (IsFloatingPoint<T>) {
|
if constexpr (IsFloatingPoint<T> || IsFloatingPoint<U>) {
|
||||||
|
if constexpr (IsFloatingPoint<U>)
|
||||||
VERIFY(isfinite(y));
|
VERIFY(isfinite(y));
|
||||||
return fmod(fmod(x, y) + y, y);
|
return fmod(fmod(x, y) + y, y);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -311,7 +311,7 @@ u16 ms_from_time(double t)
|
||||||
u8 week_day(double t)
|
u8 week_day(double t)
|
||||||
{
|
{
|
||||||
// 𝔽(ℝ(Day(t) + 4𝔽) modulo 7)
|
// 𝔽(ℝ(Day(t) + 4𝔽) modulo 7)
|
||||||
return static_cast<u8>(modulo(day(t) + 4, 7.0));
|
return static_cast<u8>(modulo(day(t) + 4, 7));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 21.4.1.11 MakeTime ( hour, min, sec, ms ), https://tc39.es/ecma262/#sec-maketime
|
// 21.4.1.11 MakeTime ( hour, min, sec, ms ), https://tc39.es/ecma262/#sec-maketime
|
||||||
|
|
|
@ -281,37 +281,37 @@ DaysAndTime balance_time(double hour, double minute, double second, double milli
|
||||||
microsecond += floor(nanosecond / 1000);
|
microsecond += floor(nanosecond / 1000);
|
||||||
|
|
||||||
// 3. Set nanosecond to nanosecond modulo 1000.
|
// 3. Set nanosecond to nanosecond modulo 1000.
|
||||||
nanosecond = modulo(nanosecond, 1000.0);
|
nanosecond = modulo(nanosecond, 1000);
|
||||||
|
|
||||||
// 4. Set millisecond to millisecond + floor(microsecond / 1000).
|
// 4. Set millisecond to millisecond + floor(microsecond / 1000).
|
||||||
millisecond += floor(microsecond / 1000);
|
millisecond += floor(microsecond / 1000);
|
||||||
|
|
||||||
// 5. Set microsecond to microsecond modulo 1000.
|
// 5. Set microsecond to microsecond modulo 1000.
|
||||||
microsecond = modulo(microsecond, 1000.0);
|
microsecond = modulo(microsecond, 1000);
|
||||||
|
|
||||||
// 6. Set second to second + floor(millisecond / 1000).
|
// 6. Set second to second + floor(millisecond / 1000).
|
||||||
second += floor(millisecond / 1000);
|
second += floor(millisecond / 1000);
|
||||||
|
|
||||||
// 7. Set millisecond to millisecond modulo 1000.
|
// 7. Set millisecond to millisecond modulo 1000.
|
||||||
millisecond = modulo(millisecond, 1000.0);
|
millisecond = modulo(millisecond, 1000);
|
||||||
|
|
||||||
// 8. Set minute to minute + floor(second / 60).
|
// 8. Set minute to minute + floor(second / 60).
|
||||||
minute += floor(second / 60);
|
minute += floor(second / 60);
|
||||||
|
|
||||||
// 9. Set second to second modulo 60.
|
// 9. Set second to second modulo 60.
|
||||||
second = modulo(second, 60.0);
|
second = modulo(second, 60);
|
||||||
|
|
||||||
// 10. Set hour to hour + floor(minute / 60).
|
// 10. Set hour to hour + floor(minute / 60).
|
||||||
hour += floor(minute / 60);
|
hour += floor(minute / 60);
|
||||||
|
|
||||||
// 11. Set minute to minute modulo 60.
|
// 11. Set minute to minute modulo 60.
|
||||||
minute = modulo(minute, 60.0);
|
minute = modulo(minute, 60);
|
||||||
|
|
||||||
// 12. Let days be floor(hour / 24).
|
// 12. Let days be floor(hour / 24).
|
||||||
auto days = floor(hour / 24);
|
auto days = floor(hour / 24);
|
||||||
|
|
||||||
// 13. Set hour to hour modulo 24.
|
// 13. Set hour to hour modulo 24.
|
||||||
hour = modulo(hour, 24.0);
|
hour = modulo(hour, 24);
|
||||||
|
|
||||||
// 14. Return the Record { [[Days]]: days, [[Hour]]: hour, [[Minute]]: minute, [[Second]]: second, [[Millisecond]]: millisecond, [[Microsecond]]: microsecond, [[Nanosecond]]: nanosecond }.
|
// 14. Return the Record { [[Days]]: days, [[Hour]]: hour, [[Minute]]: minute, [[Second]]: second, [[Millisecond]]: millisecond, [[Microsecond]]: microsecond, [[Nanosecond]]: nanosecond }.
|
||||||
return DaysAndTime {
|
return DaysAndTime {
|
||||||
|
|
|
@ -180,7 +180,7 @@ ISOYearMonth balance_iso_year_month(double year, double month)
|
||||||
year += floor((month - 1) / 12);
|
year += floor((month - 1) / 12);
|
||||||
|
|
||||||
// 3. Set month to (month − 1) modulo 12 + 1.
|
// 3. Set month to (month − 1) modulo 12 + 1.
|
||||||
month = modulo(month - 1, 12.0) + 1;
|
month = modulo(month - 1, 12) + 1;
|
||||||
|
|
||||||
// 4. Return the Record { [[Year]]: year, [[Month]]: month }.
|
// 4. Return the Record { [[Year]]: year, [[Month]]: month }.
|
||||||
return ISOYearMonth { .year = static_cast<i32>(year), .month = static_cast<u8>(month), .reference_iso_day = 0 };
|
return ISOYearMonth { .year = static_cast<i32>(year), .month = static_cast<u8>(month), .reference_iso_day = 0 };
|
||||||
|
|
|
@ -150,10 +150,10 @@ ISODateTime get_iso_parts_from_epoch(BigInt const& epoch_nanoseconds)
|
||||||
auto millisecond = ms_from_time(epoch_milliseconds);
|
auto millisecond = ms_from_time(epoch_milliseconds);
|
||||||
|
|
||||||
// 11. Let microsecond be floor(remainderNs / 1000) modulo 1000.
|
// 11. Let microsecond be floor(remainderNs / 1000) modulo 1000.
|
||||||
auto microsecond = modulo(floor(remainder_ns / 1000), 1000.0);
|
auto microsecond = modulo(floor(remainder_ns / 1000), 1000);
|
||||||
|
|
||||||
// 12. Let nanosecond be remainderNs modulo 1000.
|
// 12. Let nanosecond be remainderNs modulo 1000.
|
||||||
auto nanosecond = modulo(remainder_ns, 1000.0);
|
auto nanosecond = modulo(remainder_ns, 1000);
|
||||||
|
|
||||||
// 13. Return the Record { [[Year]]: year, [[Month]]: month, [[Day]]: day, [[Hour]]: hour, [[Minute]]: minute, [[Second]]: second, [[Millisecond]]: millisecond, [[Microsecond]]: microsecond, [[Nanosecond]]: nanosecond }.
|
// 13. Return the Record { [[Year]]: year, [[Month]]: month, [[Day]]: day, [[Hour]]: hour, [[Minute]]: minute, [[Second]]: second, [[Millisecond]]: millisecond, [[Microsecond]]: microsecond, [[Nanosecond]]: nanosecond }.
|
||||||
return { .year = year, .month = month, .day = day, .hour = hour, .minute = minute, .second = second, .millisecond = millisecond, .microsecond = static_cast<u16>(microsecond), .nanosecond = static_cast<u16>(nanosecond) };
|
return { .year = year, .month = month, .day = day, .hour = hour, .minute = minute, .second = second, .millisecond = millisecond, .microsecond = static_cast<u16>(microsecond), .nanosecond = static_cast<u16>(nanosecond) };
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue