Вопрос

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

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

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

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

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

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

Вопросы:

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

2. Почему происходит преобразование?

3. Как избежать такого рода конверсий?

Любая помощь будет здорово!

Это было полезно?

Решение

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

Другие советы

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top