2013-06-28 2 views
0

Представьте себе следующую ситуацию. Суммы добавляются в общей сложности в цикле:Добавление поплавков не дает правильного результата

float total = 0; 
float[] amounts = new float[]{...}; 
foreach(float amount in amounts) 
{ 
    total += amount; 
} 

total, как вэй, как и все amount с записываются в базу данных. Когда я вычисляю SUM(amount) в SQL, это приводит к значению, которое отличается от total. Кроме того, когда я сделать то же расчет в C#, но на этот раз при добавлении суммы к значению типа двойного,

double total = 0; 
//the rest of the code is the same as above 

затем total представляет правильное значение.

Это может быть вызвано разницей в точности между поплавком и двойным?

Обратите внимание, что это зависит от значений. Большинство результатов этого расчета являются правильными.

+1

Переменная типа float имеет только 7 цифр точности, где переменная типа double имеет 15 цифр точности. –

+0

Покажите нам поплавки, и тогда мы сможем помочь ...? –

+0

@newStackExchangeInstance: значения являются случайными (а не как «случайным образом сгенерированы», но они могут быть любыми) – bvgheluwe

ответ

2

Да. Размер поплавка SQL Server является вариантом, но вы, вероятно, имеете 8 байтов в базе данных. Когда вы используете удвоение (8 байтов) в коде C#, результаты одинаковы, когда вы используете float (4 байта), они разные. двойные значения в пределах диапазона float не будут совпадать с значениями float.

+0

I sh ould упоминают, что они хранятся как «реальные» в SQL Server. Но даже тогда сумма («реальных» значений в SQL) более точна, чем сумма значений «float» в C#. – bvgheluwe

2

Может ли это быть вызвано разницей в точности между поплавком и двойным?

Да. Иногда это может быть просто потому, что не все значения могут быть представлены в плавающей точке IEEE; во многих сценариях, где вы ожидаете «точные» суммы (деньги и т. д.), обычно лучше использовать decimal. Однако это не следует интерпретировать как означающее, что decimal является «точным» - просто потому, что способ его округления более благоприятствует тому, как мы, люди, думаем округлить.

+0

Правильно ли говорить, что 'decimal' является * более * точным, потому что он использует еще больше бит (чем' double' to представляют ценность? – bvgheluwe

+0

Одна вещь, которая может быть удивительной в .NET System.Decimal, заключается в том, что она иногда использует 29 десятичных цифр, а иногда и 28. По этой причине вычисления, такие как '800m/3m * 3m' и' 500m/3m * 3m', которые люди _expect_ являются эквивалентными, не похожи (предположим, какой из них является целым числом (с конечными нулями)). –

+1

@BartVG Из-за этого больше _precise_. –

Смежные вопросы