C# точность плавания
Может кто-нибудь, пожалуйста, объясните мне, что здесь происходит:
using System;
using System.Text;
namespace ConsoleApplication1 {
class Program {
static void Main(string[] args) {
object o = 1000000.123f;
float f= Convert.ToSingle(o);
double d = Convert.ToDouble(f);
Console.WriteLine(f.ToString("r"));
Console.WriteLine(d.ToString("r"));
Console.ReadLine();
}
}
}
Какие выводы:
1000000,13
1000000.125
Я ожидал:
Объект o должен иметь базовый тип float (кажется, это происходит [из наблюдения окна наблюдения, где он напечатан как object {float})
Это значение 1000000.123f будет сохранено в f как 1000000.125 (приближение IEEE754 в 32 битах?)
Что double также будет хранить 1000000.125 (кажется, что происходит, хотя f, кажется, не содержит того, что я ожидал)
Тот запрос формата туда и обратно на ToString вернул бы мне 1000000.125 в обоих случаях.
Может кто-нибудь сказать мне, что я делаю неправильно, чтобы получить 1000000.13 при выводе F?
1 ответ
Как вы уже заметили, число 1000000.123 хранится как 1000000.125. Это отображается как есть double.ToString()
, но усечено float.ToString()
потому что показ слишком большого количества цифр вводит в заблуждение.
Кстати, нет Convert.ToSingle(float)
потому что он просто вернет именно то, что вы передали. Ваш код на самом деле разрешается в Convert.ToSingle(double)
, Таким образом, вы (неявно) обращаетесь к double
а затем (явно) вернуться к float
, который не является, по сути.
Внимание: не доверяйте JavaScript калькуляторам с плавающей точкой. Некоторые из них утверждают, что 1000000.123 хранится как 1000000.1 с плавающей точкой одинарной точности, что, я думаю, основано на предположении, что поскольку плавающие объекты IEEE имеют точность примерно 7,22, они могут быть точно представлены в 8 цифрах. Это неверно