Раунд вниз / усечение большого поплавка [дубликат]

TL; DR: Попробуйте использовать Html.Partial вместо Renderpage


Я получал Object reference not set to an instance of an object, когда пытался сделать вид в представлении, отправив ему модель, например это:

@{
    MyEntity M = new MyEntity();
}
@RenderPage("_MyOtherView.cshtml", M); // error in _MyOtherView, the Model was Null

Отладка показала, что модель была Null внутри MyOtherView. Пока я не сменил его на:

@{
    MyEntity M = new MyEntity();
}
@Html.Partial("_MyOtherView.cshtml", M);

И это сработало.

Кроме того, причина, по которой я не имел Html.Partial для начала, заключалась в том, что Visual Studio иногда выдает ошибки, (f9), если он находится внутри другого построенного цикла foreach, хотя это не ошибка:

@inherits System.Web.Mvc.WebViewPage
@{
    ViewBag.Title = "Entity Index";
    List<MyEntity> MyEntities = new List<MyEntity>();
    MyEntities.Add(new MyEntity());
    MyEntities.Add(new MyEntity());
    MyEntities.Add(new MyEntity());
}
<div>
    @{
        foreach(var M in MyEntities)
        {
            // Squiggly lines below. Hovering says: cannot convert method group 'partial' to non-delegate type Object, did you intend to envoke the Method?
            @Html.Partial("MyOtherView.cshtml");
        }
    }
</div>

Но я смог запустить приложение без проблем с этим " ошибка". Я смог избавиться от ошибки, изменив структуру цикла foreach, чтобы выглядеть так:

@foreach(var M in MyEntities){
    ...
}

Хотя я чувствую, что это потому, что Visual Studio неправильно интерпретировала амперсанды и скобки .

4
задан nunos 15 December 2009 в 13:57
поделиться

9 ответов

В сумме двух поплавков теряется ли какая-либо точность?

Если оба поплавка имеют различную величину, и оба используют полный диапазон точности (около 7 десятичных цифр) то да, вы увидите потерю в последних местах.

Почему?

Это связано с тем, что поплавки хранятся в форме (sign) ( мантисса) × 2 (показатель степени). Если два значения имеют разные показатели и вы их добавляете, то меньшее значение будет уменьшено до меньших цифр в мантиссе (потому что оно должно адаптироваться к более крупному экспоненту):

PS> [float]([float]0.0000001 + [float]1)
1

In сумма поплавка и целое число, есть ли какая-либо потеря точности?

Да, нормальное 32-битное целое число может точно представлять значения, которые точно не вписываются в float. Поплавок все еще может хранить приблизительно то же самое число, но уже не точно. Конечно, это относится только к достаточно большим числам, т.е. е. длиннее 24 бит.

Почему?

Так как float имеет 24 бита точности и (32-разрядные) целые числа, то 32. float все равно сможет для сохранения величины и большинства значимых цифр, но последние места могут, вероятно, отличаться:

PS> [float]2100000050 + [float]100
2100000100
7
ответ дан Joey 3 September 2018 в 13:26
поделиться
  • 1
    Просто играя дьяволов, выступая здесь, в последнем пункте «Почему?». Не будет ли 24-битное целое число точным? Разве это не вопрос о том, как представлена ​​информация, а не количество бит? 128-битный флоат по-прежнему будет иметь потенциал быть неточным, не так ли? – Lazarus 15 December 2009 в 13:42
  • 2
    Лазарус: Конечно, если ваше целое вписывается в 24 бита, то float может точно представлять его. Подобное обоснование для Lua и его принятие для double как единственного числового типа данных: он может обрабатывать целые числа до 52 бит просто отлично. – Joey 15 December 2009 в 13:43

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

Если вы попытались добавить (скажем) 10 ^ 23 и 7, то он не сможет точно представить этот результат. Аналогичный аргумент применяется при добавлении float и integer - целое число будет повышаться до float.

1
ответ дан DMI 3 September 2018 в 13:26
поделиться

В обоих случаях ответ «да». Добавляя int к float, целое число преобразуется в представление с плавающей запятой до того, как добавление все равно произойдет.

Чтобы понять, почему, я предлагаю вам прочитать этот драгоценный камень: What Every Компьютерный ученый должен знать о арифметике с плавающей точкой .

0
ответ дан Gregory Pakosz 3 September 2018 в 13:26
поделиться

Точность зависит от величины исходных чисел. В плавающей запятой компьютер представляет собой номер 312 как научную нотацию:

3.12000000000 * 10 ^ 2

Число знаков после запятой в левой части (мантисса) фиксировано. Показатель также имеет верхнюю и нижнюю границу. Это позволяет отображать очень большие или очень маленькие числа.

Если вы попытаетесь добавить два числа, которые одинаковы по величине, результат должен оставаться неизменным по точности, поскольку десятичная точка не имеет для перемещения:

312.0 + 643.0 <==>

3.12000000000 * 10 ^ 2 +
6.43000000000 * 10 ^ 2
-----------------------
9.55000000000 * 10 ^ 2

Если вы попытались добавить очень большое и очень маленькое число, вы потеряете точность, потому что они должны быть сжаты в вышеуказанный формат. Рассмотрим 312 + 12300000000000000000000. Сначала вам нужно масштабировать меньшее число, чтобы выстроить его в соответствии с большим, а затем добавить:

1.23000000000 * 10 ^ 15 +
0.00000000003 * 10 ^ 15
-----------------------
1.23000000003 <-- precision lost here!

Плавающая точка может обрабатывать очень большие или очень маленькие цифры. Но он не может представлять оба одновременно.

Что касается добавления int и удвоений, int сразу превращается в double, тогда применяется вышеприведенное.

2
ответ дан Matthew Herrmann 3 September 2018 в 13:26
поделиться

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

При добавлении float к целому числу целое сначала преобразуется в float с помощью C ++, поэтому добавляются два поплавка и вводятся ошибки по тем же причинам, что и выше.

2
ответ дан moonshadow 3 September 2018 в 13:26
поделиться

В сумме двух поплавков есть ли какая-то точность? В сумме float и целого числа, есть ли какая-то точность потеряна? Почему?

Не всегда. Если сумма представляется с точностью, которую вы задаете, и вы не получите потери точности.

Пример: 0,5 + 0,75 => без потери точности x * 0,5 => без потери точности (за исключением случаев, когда x слишком мал)

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

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

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

При строгой семантике IEEE добавление двух 32-битных поплавков не должно давать более высокую точность, чем 32 бита. На практике это может потребовать дополнительной инструкции, чтобы убедиться, что вы не должны полагаться на точные и повторяемые результаты с плавающей точкой.

1
ответ дан ponce 3 September 2018 в 13:26
поделиться

В обоих случаях да:

assert( 1E+36f + 1.0f == 1E+36f );
assert( 1E+36f + 1 == 1E+36f );
0
ответ дан Sebastian 3 September 2018 в 13:26
поделиться

Точность, доступная для float, ограничена, поэтому, конечно, всегда существует риск того, что любая заданная операция опустится.

Ответ для обоих ваших вопросов - «да».

Если вы попытаетесь добавить очень большой поплавок на очень маленький, вы, например, столкнетесь с проблемами.

Или если вы попытаетесь добавить целое число в float, где целое число использует больше бит чем плавающий доступный для его мантиссы.

1
ответ дан unwind 3 September 2018 в 13:26
поделиться

Случай float + int такой же, как float + float, потому что стандартное преобразование применяется к int. В случае float + float это зависит от реализации, потому что реализация может выбрать дополнение с двойной точностью. Конечно, при сохранении результата могут быть некоторые потери.

0
ответ дан user 3 September 2018 в 13:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: