Кастинг узких типов к более широким типам, чтобы сохранить память и сохранить вычисления высокой точности ужасной идеей?

Только что обновил мой макбук с Эль Капитана до Сьерры. Простая переустановка Xquartz справилась со мной, используя ssh -X [linux server]

5
задан Daniel Schobel 28 May 2009 в 16:29
поделиться

9 ответов

Точка использования десятичной (128 бит) над двойным (64 бита) и с плавающей точкой (32 бита) обычно не связаны с размером. Это связано с базой. В то время как double и float относятся к типам с плавающей двоичной точкой, decimal - это тип с плавающей десятичной точкой - и именно эта функция позволяет представлять числа вроде 0,1 именно там, где float / double не может.

Нет концептуальной причины, по которой у нас не могло бы быть 64-битного десятичного типа, и во многих случаях этого действительно было бы достаточно - но пока такой тип не появится или вы не напишете его сами, пожалуйста не используйте «более короткие» (и двоичные с плавающей запятой) типы float / double для финансовых расчетов. Если вы это сделаете, вы столкнетесь с проблемой.

Если вы предлагаете написать тип хранилища, который может преобразовывать в / из десятичного числа и по-прежнему является плавающим десятичным типом, это звучит как потенциально хорошая идея, даже если он не умеет производить какие-либо вычисления. Вам нужно быть очень осторожным, когда вы думаете о том, что делать, если вас когда-либо просят преобразовать десятичное значение, которое вы не можете точно представить. Если честно, мне было бы интересно увидеть такой типаж. Хмм ...

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

16
ответ дан 18 December 2019 в 05:40
поделиться

64-битные числа с плавающей запятой не могут поддерживать точность финансовых данных. Дело не в размере, а в том, какую систему счисления используют типы данных; double использует base-2, decimal - base-10, а base-2 не может представлять точные десятичные дроби с основанием 10, даже если у него была точность в 1000 бит.

Не верите мне? Запустите это:

double d = 0.0;
for (int i = 0; i < 100; i++)
    d += 0.1;
Console.WriteLine(d);

> 9.99999999999998

Если вам нужны вычисления с основанием 10, вам нужен десятичный тип.

(Правка: черт побери, снова Джон Скит ...)

Если десятичный тип действительно является узким местом, вы можете использовать длинное число пенни (или 1/8 цента или другую единицу) вместо десятичных долларов.

5
ответ дан 18 December 2019 в 05:40
поделиться

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

3
ответ дан 18 December 2019 в 05:40
поделиться

Это кажется совершенно разумным, если 64-битная плавающая точка действительно достаточна для представления желаемой точности. Десятичная дробь повышенной точности, как вы говорите, часто используется исключительно для минимизации совокупных ошибок при выполнении нескольких операций.

2
ответ дан 18 December 2019 в 05:40
поделиться

Вполне разумно хранить ваши числа в 64 бит, приведите их к десятичному типу для вычислений, и верните результат обратно к 64-битному, если вы не возражаете против снижения производительности.

Нам нужен такой уровень точности там, где я работаю, так что это именно то, что мы делаем здесь. Мы получаем снижение скорости на два порядка за счет выполнения приведений, но нам никогда не нужно беспокоиться о больших ошибках в арифметике с плавающей запятой. Без преобразования расчет может быть совершенно неточным, в зависимости от диапазона чисел и типа выполняемого вычисления.

Подробнее об арифметике с плавающей запятой и о том, почему ошибки могут закрасться в ваши вычисления, см. В разделе «Что каждый компьютер Ученый должен знать об арифметике с плавающей запятой "на http://docs.sun.com/source/806-3568/ncg_goldberg.html

3
ответ дан 18 December 2019 в 05:40
поделиться

Вам необходимо провести численный анализ, чтобы увидеть, является ли практика (сохранение 128 бит) нелепой, или просто ленивой, или действительно необходимой.

0
ответ дан 18 December 2019 в 05:40
поделиться

Из MSDN decimal: неявное преобразование между типами с плавающей запятой и десятичным типом отсутствует; следовательно, для преобразования между этими двумя типами необходимо использовать приведение.

Похоже, это НЕОБХОДИМО выполнить приведение в случае, который вы используете.

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

Вы можете рассмотреть возможность создания / поиска реализации 64-битной BCD (двоично-десятичной кодировки), которую вы можете использовать в своей системе.

0
ответ дан 18 December 2019 в 05:40
поделиться

Является ли «просто добавить больше памяти» приемлемым ответом?

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

0
ответ дан 18 December 2019 в 05:40
поделиться

Как уже отмечалось в большинстве других сообщений, преобразование между 128-битным десятичным и 64-битным представлениями с плавающей запятой не является преобразованием это всегда будет поддерживать точность.

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

Другой подход может заключаться в улучшении алгоритмической эффективности вашей системы, а не в «сжатии» типа хранилища. Вам действительно нужны все эти данные в памяти сразу? Можете ли вы каким-то образом виртуализировать его?

В противном случае, учитывая объем данных, которыми вы управляете, вы можете захотеть организовать их таким образом, чтобы уменьшить избыточность. Например, не каждая акция имеет историческую цену назад во времени (некоторые компании существуют недостаточно далеко назад). Так что организуйте свои данные в виде словаря цен на акции по дням (или годам), а не в виде табличной структуры для каждой акции. Могут быть и другие альтернативы в зависимости от того, как доступны ваши данные и как вы собираетесь проводить с ними вычисления.

2
ответ дан 18 December 2019 в 05:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: