Почему число с плавающей запятой больше двойного после вычисления того же значения? Почему число с плавающей точкой не может быть неявно преобразовано в десятичное - PullRequest
0 голосов
/ 01 июля 2018

Так много арифметических вопросов о SO, особенно с плавающей запятой, поэтому я объединяю свои 2 вопроса вместе.

  1. Зачем плавать 0.3333333> double 0.333333333333333?

Вот программа, доказывающая это.

        static void Main(string[] args)
        {
            int a = 1;
            int b = 3;
            float f = Convert.ToSingle(a) / Convert.ToSingle(b);
            double db = Convert.ToDouble(a) / Convert.ToDouble(b);
            Console.WriteLine(f > db);
            Console.Read();
        }
  1. Почему float нельзя неявно преобразовать в decimal, а int можно?

, например

decimal d1 = 0.1f; //error
decimal d2 = 1; //no error

Ответы [ 2 ]

0 голосов
/ 01 июля 2018
  1. Когда цифры в исходном тексте, такие как .3333333, конвертируются в числа с плавающей запятой, они округляются до ближайшего представимого значения. Бывает, что ближайшее значение float к .3333333 немного больше, чем .3333333; это 0,333333313465118408203125, в то время как значение double, ближайшее к 0,333333333333333, немного меньше этого значения; это 0,333333333333332981762708868700428865849971771240234375. Так как значение 0,333333313465118408203125 превышает 0,333333333333332981762708868700428865849971771240234375, f > db оценивается как истинное.

  2. Я не знаком с правилами C # и его десятичного типа. Тем не менее, я подозреваю, что причина decimal d1 = 0.1f; запрещена, в то время как разрешено decimal d2 = 1;, состоит в том, что не все значения float могут быть преобразованы в decimal без ошибок, в то время как все значения int могут быть преобразованы в decimal без ошибок , Согласно Microsoft , decimal использует значение из 96 цифр, что достаточно для точного представления любого int. Тем не менее, он имеет меньший диапазон, чем float, с наибольшим конечным значением, равным 2 96 -1, около 7,9228 • 10 28 . Наибольшее конечное float составляет 2 128 -2 104 , около 3,4028 • 10 38 .

0 голосов
/ 01 июля 2018

Для вашего первого вопроса float s фактически преобразуются в double s, когда вы используете для них оператор >. Если вы напечатаете (double)f, вы увидите его значение:

0.333333343267441

Пока db равно:

0.333333333333333

По второму вопросу, хотя не существует неявного преобразования из float в decimal, существует явное, поэтому вы можете использовать приведение:

float a = 0.1f; 
decimal d = (decimal)a;

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...