Удваивает Умножение, Прерванное.NET? [дубликат]

Лучший способ сделать это в C++ должно, вероятно, использовать итератор (или лучше, диапазон) адаптеры, которые лениво преобразуют последовательность, поскольку это пересекается.

В основном,

vector<value_type> range;
foreach(value_type v, range | reversed)
    cout << v;

Дисплеи диапазон "диапазон" (здесь, это пусто, но я абсолютно уверен, что можно добавить элементы сами), в обратном порядке. Конечно, просто итерация диапазона не полезна, но передача, что новый диапазон к алгоритмам и материалу довольно прохладен.

Этот механизм может также использоваться для намного более мощного использования:

range | transformed(f) | filtered(p) | reversed

лениво вычислит диапазон "диапазон", где функция "f" применяется ко всем элементам, удалены элементы, для которых "p" не верен, и наконец получающийся диапазон инвертируется.

синтаксис Канала является самым читаемым IMO, учитывая он - инфикс. Повышение. Обновление библиотеки диапазона, ожидающее, обзор реализует это, но довольно просто сделать это самостоятельно также. С лямбдой DSEL еще более здорово генерировать функцию f и предикат p встроенный.

53
задан sth 14 September 2009 в 05:47
поделиться

5 ответов

Потому что вы неправильно поняли арифметику с плавающей запятой и то, как хранятся данные.

На самом деле, ваш код фактически не выполняет никаких арифметических действий во время выполнения в данном конкретном случае - компилятор сделает это, а затем сохранит константу в сгенерированном исполняемом файле. Однако он не может сохранить точное значение 6,9, потому что это значение не может быть точно представлено в формате с плавающей запятой, точно так же, как 1/3 не может быть точно сохранено в конечном десятичном представлении.

Посмотрите, эта статья поможет вам.

156
ответ дан 7 November 2019 в 08:14
поделиться

почему платформа не работает? это и скрыть эту проблему от меня и дать мне правильный ответ, 0,69 !!!

Перестаньте вести себя как менеджер дилберта и примите тот факт, что компьютеры, хотя и крутые и классные, имеют ограничения. В вашем конкретном случае он не просто «скрывает» проблему, потому что вы специально сказали ему не делать этого. Язык (компьютер) предоставляет альтернативы формату, который вы не выбрали. Вы выбрали double, у которого есть определенные преимущества перед десятичным числом и некоторые недостатки. Теперь, зная ответ, вы расстроены тем, что недостатки не исчезают волшебным образом.

Как программист, вы несете ответственность за сокрытие этого недостатка от менеджеров, и есть много способов сделать это. Однако создатели C # несут ответственность за правильную работу с плавающей запятой, и исправление с плавающей запятой может иногда приводить к неправильным математическим вычислениям.

То же самое будет с любым другим методом хранения чисел, поскольку у нас нет бесконечных битов. Наша работа как программистов - работать с ограниченными ресурсами, чтобы делать крутые вещи. Они проложили 90% пути, просто принеси фонарик домой.

53
ответ дан 7 November 2019 в 08:14
поделиться

По той же причине, по которой 1/3 в десятичной системе получается 0,3333333333333333333333333333333333333333333, а не точная дробь, которая бесконечно длинна.

8
ответ дан 7 November 2019 в 08:14
поделиться

но почему фреймворк не работает над этим и не скрывает эту проблему от меня и не дает мне правильный ответ, 0,69 !!!

Поскольку вы сказали ему использовать двоичную с плавающей запятой , а решение состоит в использовании десятичной с плавающей запятой , вы предлагаете, чтобы фреймворк игнорировал указанный вами тип и использовал Вместо этого decimal , что намного медленнее, потому что оно не реализовано напрямую на аппаратном уровне.

Более эффективное решение - не выводить полное значение представления и явно указывать точность, требуемую для вывода. Если вы отформатируете вывод до двух десятичных знаков, вы увидите ожидаемый результат. Однако если это финансовое приложение десятичное - это именно то, что вам следует использовать - вы » мы видели Супермена III (и офисное пространство), не так ли;)

Обратите внимание, что все это конечное приближение бесконечного диапазона, просто десятичное и двойное используйте другой набор приближений. Преимущество десятичной дроби в том, что она дает такие же приближения, как если бы вы выполняли вычисления самостоятельно. Например, если вы рассчитали 1/3, вы в конечном итоге перестанете писать тройки, когда это будет «достаточно хорошо».

11
ответ дан 7 November 2019 в 08:14
поделиться

И 0,69 можно легко представить в двоичное, одно двоичное число для 69 и другой для обозначения положения десятичное место.

Я думаю, что это распространенная ошибка - вы думаете о числах с плавающей запятой, как если бы они были десятичными (то есть десятичными - отсюда мой акцент).

Итак - вы Вы думаете, что это двойное число состоит из двух целых частей: 69 и разделите на 100 , чтобы переместить десятичный разряд - что также может быть выражено как:
69 x 10 в степени -2 .

Однако числа с плавающей запятой сохраняют «положение точки» как основание-2 .

Фактически ваше число с плавающей запятой сохраняется как:
68999999999999995 x 2 в степени некоторого большого отрицательного числа

Это не такая большая проблема, как только вы к нему привыкнете - большинство людей знают и ожидают, что 1/3 не может быть точно выражена как десятичная или процент. Просто дроби, которые могут

15
ответ дан 7 November 2019 в 08:14
поделиться