Почему данные, хранящиеся в типе данных Float, считаются приблизительными? - PullRequest
2 голосов
/ 10 сентября 2011

Я никогда не понимал, почему тип данных с плавающей запятой считается приближенным, а тип десятичного числа считается точным. Я ищу хорошее объяснение, спасибо.

Ответы [ 4 ]

3 голосов
/ 10 сентября 2011

Ну, это зависит от вашей точки зрения.И float, и decimal (при условии, что вы имеете в виду типы, подобные тем, что в C #) представляют точные значения.Однако в обоих случаях преобразования (и арифметические) могут заканчиваться аппроксимациями, в которых сохраненное значение является только «наиболее близким к теоретическому точному значению».

В частности - и это важнонормальная причина идеи "float приблизительная" - это преобразование литеральных значений в коде:

float f = 0.1f;
decimal d = 0.1m;

Эти литералы выражаются в виде десятичных чисел - и 0,1 можетне быть точно представлен в виде двоичного числа с плавающей запятой.Тем не менее, может быть представлен точно в виде десятичного числа с плавающей запятой.

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

// Imaginary syntax - doesn't work in C#!
float f = 0b0.11f;

, то не было бы никакихаппроксимация здесь - это значение будет точно таким же, как десятичное значение 0,75.

В основном все дело в предвзятости людей думать о числах в базе 10. С точки зрения иностранца с 3 пальцами наодна рука, которая представляла значения в базе 3 естественным образом, и float, и decimal были бы "приближениями".

(Есть и другие существенные различия между float и decimal в C # вокруг значительногоцифры против диапазона значений, но это другое дело.)

1 голос
/ 10 сентября 2011

ну, вы правы - вводить в заблуждение такое ошибочное утверждение.Чтобы полностью понять, вам нужно понять две вещи.

Во-первых, десятичная дробь предназначена для хранения (точно) десятичных значений с фиксированным количеством десятичных знаков.как правило, деньги (например, десятичные дроби - центы).это очень конкретный случай использования.это не точное хранилище для любого значения;это только для десятичных значений с фиксированным количеством десятичных точек, и реализация адаптирована для этого правильно.

секунда, числа с плавающей запятой предназначены для более общего типа данных - они используются для хранения «любого» значения- и реализация отражает это (так, например, реализация нацелена на охват широкого диапазона масштабов и максимально эффективную поддержку операций).в частности, он использует двоичное представление, которое не может точно представлять все десятичные значения.так, например, он может хранить точно 0,5, но не может хранить точно 0,1.это просто факт использования используемого двоичного представления - базы-2, но это означает, что для денег плавающие символы не являются хорошей идеей: если вы не можете хранить 0,10 точно как число с плавающей точкой, то любые вычисления с участием 10 центов могут накапливаться неожиданноошибки.

другими словами, оба имеют свои ограничения.единственный способ, которым десятичная дробь является «более точной», чем float, состоит в том, что ее легче понять: значения, для которых она работает, четко определены, полезны и соответствуют «естественному» представлению base 10, которое мы используем.напротив, гораздо сложнее понять, какие значения будут точно храниться с помощью чисел с плавающей точкой, а какие нет, поскольку они зависят от базового представления базы 2.

0 голосов
/ 10 сентября 2011

Вы можете получить все кровавые подробности здесь , но в основном IEEE с плавающей запятой хранит числа в виде целочисленной мантиссы, умноженной на два, возведенной в целую степень. Подобно тому, как некоторые дроби, например, одна треть, не могут быть выражены точно как неповторяющееся десятичное число с основанием 10, многие дроби не могут быть выражены точно как двоичные дроби. Это часто удивляет, потому что, хотя мы использовали 1/3 в качестве повторяющейся десятичной дроби, мы интуитивно ожидаем, что 1/5 будет легко представляться как 0,2, но в двоичной системе это повторяющаяся десятичная дробь (двоичная?), Которая не может быть точно представлена ​​в конечном числе. бит.

0 голосов
/ 10 сентября 2011
Значение

A decimal точно равно значению его строкового представления (правка: в десятичном виде, как отмечает Skeet), а decimal также может точно представлять десятичные числа с ограниченным количеством цифр. С другой стороны, значение float часто будет отличаться от его строкового представления, и существует много десятичных чисел (например, 0,1), которые нельзя точно представить как float.

...