Информация об изменениях

Сообщение Re: Угадай-ка от 09.12.2022 14:48

Изменено 09.12.2022 14:49 vmpire

Re: Угадай-ка
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Сабж, что выведет код:

НС>
НС>Console.WriteLine(TimeSpan.Parse("23:00:00").TotalHours);
НС>Console.WriteLine(TimeSpan.Parse("24:00:00").TotalHours);
НС>


Да, действительно, забавно.
Посмотрел в исходники — там хитрый pattern matching.
После сопоставления по формату происходит проверка диапазонов, если не попали — считаем вариант матчинга неуспешным и переходим к следующему.
Сделано это потому, что один формат может иметь несколько смыслов.
Богатое поле распахал для скрытых багов.

if (inv)
{
    if (raw.FullHMSMatch(TimeSpanFormat.PositiveInvariantFormatLiterals))
    {
        positive = true;
        match = TryTimeToTicks(positive, zero, raw._numbers0, raw._numbers1, raw._numbers2, zero, out ticks); // Вот это сопоставление не проходит, так как _numbers0 >= 24
        overflow = overflow || !match;
    }

    if (!match && raw.FullDHMMatch(TimeSpanFormat.PositiveInvariantFormatLiterals))
    {
        positive = true;
        match = TryTimeToTicks(positive, raw._numbers0, raw._numbers1, raw._numbers2, zero, zero, out ticks); // Поэтому идём сюда. В этом формате те же разделители и то же количество элементов, отличие только в их числовом значении
        overflow = overflow || !match;
    }

    ...

}

private static bool TryTimeToTicks(bool positive, TimeSpanToken days, TimeSpanToken hours, TimeSpanToken minutes, TimeSpanToken seconds, TimeSpanToken fraction, out long result)
{
    if (days._num > MaxDays ||
        hours._num > MaxHours ||
        minutes._num > MaxMinutes ||
        seconds._num > MaxSeconds ||
        !fraction.NormalizeAndValidateFraction())
    {
        result = 0;
        return false;
    }

...

    return true;
}
Re: Угадай-ка
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Сабж, что выведет код:

НС>
НС>Console.WriteLine(TimeSpan.Parse("23:00:00").TotalHours);
НС>Console.WriteLine(TimeSpan.Parse("24:00:00").TotalHours);
НС>


Да, действительно, забавно.
Посмотрел в исходники — там хитрый pattern matching.
После сопоставления по формату происходит проверка диапазонов, если не попали — считаем вариант матчинга неуспешным и переходим к следующему.
Сделано это потому, что один формат может иметь несколько смыслов.
Богатое поле распахали для скрытых багов.

if (inv)
{
    if (raw.FullHMSMatch(TimeSpanFormat.PositiveInvariantFormatLiterals))
    {
        positive = true;
        match = TryTimeToTicks(positive, zero, raw._numbers0, raw._numbers1, raw._numbers2, zero, out ticks); // Вот это сопоставление не проходит, так как _numbers0 >= 24
        overflow = overflow || !match;
    }

    if (!match && raw.FullDHMMatch(TimeSpanFormat.PositiveInvariantFormatLiterals))
    {
        positive = true;
        match = TryTimeToTicks(positive, raw._numbers0, raw._numbers1, raw._numbers2, zero, zero, out ticks); // Поэтому идём сюда. В этом формате те же разделители и то же количество элементов, отличие только в их числовом значении
        overflow = overflow || !match;
    }

    ...

}

private static bool TryTimeToTicks(bool positive, TimeSpanToken days, TimeSpanToken hours, TimeSpanToken minutes, TimeSpanToken seconds, TimeSpanToken fraction, out long result)
{
    if (days._num > MaxDays ||
        hours._num > MaxHours ||
        minutes._num > MaxMinutes ||
        seconds._num > MaxSeconds ||
        !fraction.NormalizeAndValidateFraction())
    {
        result = 0;
        return false;
    }

...

    return true;
}