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 цифрах. Это неверно

Другие вопросы по тегам