Минутка WTF-11: посчитай их правильно-2
От: Sinix  
Дата: 16.09.16 20:00
Оценка: 20 (4)
Развиваем тему
Автор: Sinix
Дата: 15.09.16
, на этот раз дуплетом.

1.
        struct Wrapper
        {
            public Wrapper(float value)
            {
                Value = value;
            }
            public float Value { get; }
        }


2.
        struct Wrapper2
        {
            public Wrapper2(decimal value)
            {
                Value = value;
            }
            public decimal Value { get; }
        }


Что не так? На этот раз не перфоманс. Подсказка отдельным постом, чтоб интригу не ломать.
Отредактировано 07.01.2017 16:45 Sinix . Предыдущая версия . Еще …
Отредактировано 16.09.2016 20:01 Sinix . Предыдущая версия .
минутка wtf
Re: Минутка WTF-11: посчитай их правильно-2
От: Sinix  
Дата: 16.09.16 20:16
Оценка:
Здравствуйте, Sinix, Вы писали:

  Подсказка, пока только для первого куска кода
Читаем комментарий вот тут (строка 41).

Ну и ещё одна:
  Спойлер!
https://en.wikipedia.org/wiki/Signed_zero


В качестве компенсации за подсказку: с какими ещё встроенными типами может возникнуть так же проблема?
Re[2]: Минутка WTF-11: посчитай их правильно-2
От: StatujaLeha на правах ИМХО
Дата: 16.09.16 21:52
Оценка: 75 (2) +1
Здравствуйте, Sinix, Вы писали:
    class Program
    {
        static void PrintArray<T>(T[] S)
        {
            Console.WriteLine(string.Join(", ", S.Select(e => e.ToString())));
        }

        static void Main(string[] args)
        {
            //WTF10.Run(args);

            //Оптимизация приложений на платформе .NET с использованием языка C# By Саша Голдштейн, Дима Зурбалев, Идо Флатов, стр. 140
            //CanCompareBits возвращает истинное значение, если выполняется одно из следующих условий:
            //Тип значения содержит только поля простых типов и не переопределяет метод Equals.
            //Тип значения содержит только поля типов значений, для которых выполняется условие (1) и не переопределяет метод Equals.
            //Тип значения содержит только поля типов значений, для которых выполняется условие (2) и не переопределяет метод Equals.

            var a = new Wrapper(0.0f);
            var b = new Wrapper(-0.0f);

            //Семантически одинаковы, но бинарное представление различно
            //Прямое побитовое сравнение дает False
            Console.WriteLine(a.Equals(b));
            PrintArray(BitConverter.GetBytes(a.Value));
            PrintArray(BitConverter.GetBytes(b.Value));

            //Семантически одинаковы, но бинарное представление различно
            //Decimal - это value type но переопределяет Equals
            //Прямого побитового сравнения нет
            //True
            var c = new Wrapper2(decimal.Parse("1.00", NumberStyles.Any, CultureInfo.InvariantCulture));
            var d = new Wrapper2(decimal.Parse("1.0", NumberStyles.Any, CultureInfo.InvariantCulture));

            Console.WriteLine(c.Equals(d));
            PrintArray(decimal.GetBits(c.Value));
            PrintArray(decimal.GetBits(d.Value));
        }
    }
Re: Минутка WTF-11: посчитай их правильно-2
От: Слава  
Дата: 16.09.16 23:03
Оценка:
Здравствуйте, Sinix, Вы писали:


S>Развиваем тему
Автор: Sinix
Дата: 15.09.16
, на этот раз дуплетом.

S>Что не так? На этот раз не перфоманс. Подсказка отдельным постом, чтоб интригу не ломать.

Зачем (накойхер) нужен знаковый нуль в типе для хранения денег и литров? Какой физический смысл у знакового нуля? Правильно, никакого. "Мы вам налили почти ноль литров бензина, а вы нам должны за это почти ноль рублей денег".
Re[2]: Минутка WTF-11: посчитай их правильно-2
От: Lexey Россия  
Дата: 16.09.16 23:50
Оценка: 6 (1)
Здравствуйте, Слава, Вы писали:

С>Зачем (накойхер) нужен знаковый нуль в типе для хранения денег и литров? Какой физический смысл у знакового нуля? Правильно, никакого. "Мы вам налили почти ноль литров бензина, а вы нам должны за это почти ноль рублей денег".


Видимо, ноги растут из того, что может быть округление до 0, а потом деление на результат. В зависимости от того, с какой стороны округляли, результат будет либо +inf, либо -inf. Но, вообще, выглядит странно, да.
"Будь достоин победы" (c) 8th Wizard's rule.
Re[3]: Минутка WTF-11: посчитай их правильно-2
От: Sinix  
Дата: 17.09.16 07:31
Оценка:
Здравствуйте, StatujaLeha, Вы писали:

SL>...

Бинго!

но и это ещё не всё.
        static void Main(string[] args)
        {
            var m1 = 295.50000000000000000000000000m;
            var m2 = 295.5m;

            Console.WriteLine("Equals: "+ m1.Equals(m2));
            Console.WriteLine("HashCodeEquals: "+ m1.GetHashCode().Equals(m2.GetHashCode()));
            Console.WriteLine("Приятной отладки!");

            Console.ReadKey();
        }


Лучи любви посылать сюда, исторические раскопки тут.

Ну и на закуску всё тот же вопрос: какой ещё из стандартных типов лучше не засовывать в структуру без переопределённого GetHashCode()?
Re[2]: Минутка WTF-11: посчитай их правильно-2
От: Sinix  
Дата: 17.09.16 07:52
Оценка:
Здравствуйте, Слава, Вы писали:

С>Зачем (накойхер) нужен знаковый нуль в типе для хранения денег и литров?

Мсье знает толк в извращениях

Длинный ответ тут: https://en.wikipedia.org/wiki/Signed_zero . Хинт: чему равен 1/-0?
Короткий — привет из времён, когда компьютеры использовали в первую очередь для общественно полезных вещей типа прогноза погоды или моделирования ядерных взрывов.


Оффтоп: Чтоб не отвечать про "что ж тогда бесполезное?": гугл подсказывает совершенно чудесное:

Ядерные испытания HD1080p Toccata and Fugue in D minor И.C. Бах
от: МЦЯО НИЯУ МИФИ

вот как-то так.
Re[4]: Минутка WTF-11: посчитай их правильно-2
От: StatujaLeha на правах ИМХО
Дата: 17.09.16 11:13
Оценка: 46 (1) +1
Здравствуйте, Sinix, Вы писали:

S>Ну и на закуску всё тот же вопрос: какой ещё из стандартных типов лучше не засовывать в структуру без переопределённого GetHashCode()?

double — по той же причине, что и float.
bool — потому что представление implementation defined.

        [StructLayout(LayoutKind.Explicit)]
        public struct Union
        {
            [FieldOffset(0)]
            public bool ValueBool;
            [FieldOffset(0)]
            public byte ValueByte;
        }


        var v = new Union();
        for (byte k = 0; k < 5; ++k)
        {
            v.ValueByte = k;
            Console.WriteLine("ValueByte: {0}, ValueBool: {1}", k, v.ValueBool);
        }
Re[5]: Минутка WTF-11: посчитай их правильно-2
От: Sinix  
Дата: 17.09.16 12:04
Оценка: 4 (1) +1
Здравствуйте, StatujaLeha, Вы писали:

S>>Ну и на закуску всё тот же вопрос: какой ещё из стандартных типов лучше не засовывать в структуру без переопределённого GetHashCode()?

SL>double — по той же причине, что и float.
SL>bool — потому что представление implementation defined.
Ага. В общем, вопрос из разряда "фиг угадаешь", поэтому не будем показывать пальцем, но это был DateTime: DateTimeKind.Local и DateTimeKind.Unspecified, чтоб их.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.