Большие числа округляются [c #] - PullRequest
2 голосов
/ 16 июля 2009

У меня тут какая-то странная проблема. У меня есть таблица базы данных, которая имеет огромное значение хранится в столбце. Мое приложение (C #) читает это значение и сохраняет тип double . Это приложение вставит то же значение в другую таблицу. Примечание: я не делаю никаких вычислений / обработки значения, считанного из первой таблицы. Он просто сохраняется для обновления второй таблицы.

Проблема здесь в том, что вторая таблица получает немного другое значение, чем в первой таблице. Похоже, число округляется, когда я сохраняю тип double.

Вот пример значений.

Исходное значение: 18014398509481984

Значение, скопированное в новую таблицу: 18014398509482000

Значения выглядят по-разному, но в действительности оба одинаковы. Я выполнил поиск в Google с 18014398509481984 - 18014398509482000 в качестве поискового запроса, и он вернул результат 0 , что означает, что они одинаковы.

Вопросы

1 - Если оба значения одинаковы, почему второе значение выглядит иначе? Я вижу 1984 , превращенный в 2000 .

2 - Почему происходит конвертация?

3 - Как я могу избежать этого типа преобразований?

Любая помощь будет отличной!

Ответы [ 4 ]

5 голосов
/ 16 июля 2009

Попробуйте использовать System.Decimal для сохранения значения из первой таблицы вместо System.Double. System.Double не содержит достаточно значащих цифр для точного хранения этого большого значения.

3 голосов
/ 16 июля 2009

Значение двойной точности имеет точность только до 15 или 16 десятичных цифр (см. здесь для объяснения). Если вам нужно хранить больше, чем это, вам придется использовать другой числовой формат. Если вы хотите работать с очень большими целыми числами, не теряя точности, существуют различные классы, которые помогут вам подобрать этот .

Если вы получаете значение из SQL, убедитесь, что ваш целевой тип данных в .NET соответствует - например, bigint для C # long в SQL - чтобы избежать таких проблем округления.

2 голосов
/ 16 июля 2009

Вам нужно хранить их как числа с плавающей запятой?

Если нет, то вместо этого вы можете использовать 64-разрядные целые числа: BIGINT в базе данных и long / Int64 в вашем приложение.

Они имеют диапазон от –9,223,372,036,854,775,808 до 9,223,372,036,854,775,807 и не имеют проблем с точностью / точностью.

2 голосов
/ 16 июля 2009

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

Обычно обходной путь заключается в том, чтобы избежать значений с плавающей запятой (попробуйте Int64), использовать более точный тип (десятичный) или учесть ошибку и выполнить 'приблизительно равно'.

...