Погрешность округления.NET в ToString (“f2”)

Привет у меня есть этот код в C#:

float n = 2.99499989f;
MessageBox.Show("n = " + n.ToString("f2", CultureInfo.InvariantCulture));

И этот код в C++:

float n = 2.99499989f;
printf("n = %.2f", n);

Сначала выводы 3.00.
Вторые выводы 2.99.

У меня нет подсказки, почему это происходит.

Обновление:

Я также попробовал Objective C, который NSLog и вывод 2.99.

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

float n = 2.99499989f;
float round = (float)Math.Round(n, 2);
MessageBox.Show("round = " + round.ToString(CultureInfo.InvariantCulture));

Этот код показывает 2.99, но вычисляет вокруг в двойной точности. Я не могу найти Математику. RoundF.

6
задан Filip Kunc 18 January 2010 в 18:28
поделиться

5 ответов

Использование BitConverter.GetBytes и распечатывание фактических изготовленных байтов показывает, что это не A компилятор Разница - в обоих Случаи, фактическое накопленное значение поплавка 0x403Fae14 , который этот удобный калькулятор говорит мне, является точное значение

2.99499988555908203125

Разница, поэтому должна лгать в разных поведении Printf и ToString . Больше, чем я не могу сразу сказать.

6
ответ дан 17 December 2019 в 02:29
поделиться

Первый раундут номер неправильно.

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

Может быть, некоторые проблемы с плавающей точкой-точками? 2.9949 ... на самом деле раунды до более 2,995?

0
ответ дан 17 December 2019 в 02:29
поделиться

Разве это не связано с тем, что 'float' не является 'этим' точным ?

Проверьте это, когда вы используете десятичное число:

        // float
        Console.WriteLine (2.99499989f.ToString ("f2"));
        // The above line outputs 3.00

        // decimal
        Console.WriteLine (2.99499989M.ToString ("f2"));
        // The above line outputs 2.99

Возможно float не может представлять 2.99499989 или что-то в этом роде как 2.99.
Посмотрите также, что происходит, когда вы делаете это:

// float
Console.WriteLine (2.98499f.ToString ("f2"));
// The above line outputs 2.99
0
ответ дан 17 December 2019 в 02:29
поделиться

Нет, нет режима стандартов IE6 стандартов, поскольку Microsoft уже покинула режим стандартов IE6 с выпуском IE7.

IE8 построен на - и в значительной степени совместим с ошибками с - IE7. Но режим стандартов IE7 уже не был совместимым с ошибками с помощью режима стандартов IE6. Microsoft не собирается сходить с ума, пытаясь выкопать и повторно реализовать ошибки IE6 в IE8, когда в их коллективном уме эти ошибки уже ушли навсегда, так как разработчики , безусловно, должны быть обновлены свои сайты для работы с IE7 уже.

Конечно, на самом деле ужасных WebApps, которые полагаются на ошибки IE6, все еще существуют, поэтому удручающее число корпораций все еще застряло с IE6, что делает весь мир хуже для всех. Было бы полезно представить функциональность эмулироваться функциональность в IE7, так что совместимость IE6 может быть сохранена. Однако никто не думал об этом в тот момент, поэтому ушло навсегда, и целая нагрузка корпоративных обновлений Vista была прервана из-за отсутствия совместимости IE6. Упс!

(О, дорогой. Если бы только кто-то не интегрировался, т.е. с ОС, у нас не было бы все это трудности: можно запускать несколько версий IE, и, следовательно, каждая новая версия не должна будет сохранять ошибки предыдущего версия. Т.е. будет меньше, быстрее, лучше; пользователи могут обновить без боязневой потери функциональности; с большим количеством модернизации мы могли бы автор новых веществ в IE8 более легко; и MS сделали бы больше деньги на ОС Обновления. Забавно, как эти решения приходят, чтобы укусить вас, а?)

-121--3391013-

Точность поплавки составляет 2 ^ {- 23} или около 0,0000001192 (относительная ошибка). Смотри, 2.995-2.99499989 = 0,00000011. Относительная ошибка составляет 3,6 * 10 ^ {- 8} .

Если какой-то компилятор читает все цифры 2.99499989F , то результат является числом более 2,995. Но если другой компилятор читает только 2.994999 (потому что точность менее 2 ^ {- 23}, а последняя цифры не важны), тогда результат является числом менее 2,995

0
ответ дан 17 December 2019 в 02:29
поделиться

Номер 2.99499989F не может быть представлен точно в IEEE754. По-видимому, PrintF и ToString обрабатывают эту ситуацию по-разному.

-1
ответ дан 17 December 2019 в 02:29
поделиться
Другие вопросы по тегам:

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