Блог им. Burger

Вопрос к программерам на C#.

Есть 3 переменных:
a — тип Int;
b — тип Int;
c — тип Long
Столкнулся с тем, что в выражении:
с = a * b;
правая часть, по умолчанию, сначала преобразуется
в Int, а потом в Long. Соответсвенно при больших
a и b и «переполнении» Int (скажем 300 000 и 10 000)
результат получается некорректный.
Приходится заморачиваться конструкцией:
c = Convert.ToInt64(a) * Convert.ToInt64(b);
По-другому никак не реализовать корректный расчёт?
★1
20 комментариев
int хранит до 2 147 483 647. Про какие переполнения при 300 000 или 10 000 вы говорите?

Лонг — максимум в 9 223 372 036 854 775 807
Ориентируетесь на соответствующие значения в а и b.
Рустам TradeInWest.ru, 300 000 * 10 000 = 3 000 000 000,
Int переполнится и «обрежет» значение, при этом ошибки
не будет.
Точнее «перевернёт» значение, поскольку первый бит,
как правило у компиляторов знаковый. По крайней мере
так делает мой SharpDevelop 4.2
Андрей Кучумов, а, вы про произведение уже говорите, понял.
ну а тогда чем не нравится преобразование множителей в более «старшие» типы?
Что смущает? усложнение читаемости кода? лишние преобразования или еще что?
Рустам TradeInWest.ru, в целом устраивает, но вдруг,
где ещё «вылезет» переполнение, а я не замечу
(на тестинге не отловлю).
Может есть какая-нить глобальная установка компилятору,
как по-умолчанию делать неявные преобразования…
Андрей Кучумов, ну и вывод?
Если такая большая неопределенность везде (хотя я сомневаюсь), то ставь везде по максимуму типы.

Хотя это и дурной стиль. По канонам — надо максимально детально планировать архитектуру и типы подбирать под реальные потребности. Но мы живем не в идеальном мире.
Рустам TradeInWest.ru, обычно цену я запихиваю вообще
в Int16 или UInt16, по возможности. Тут тоже может
вылезти «переполнение», хотя вроде код прошерстил…
Андрей Кучумов, цену в инт? уай?
или ты цены всегда умножаешь на какой-то множитель, чтобы было целым?

Уж что что, а цену сам Бог велел в double или decimal (лучше) пихать. как мне кажется.
Рустам TradeInWest.ru, а смысл? Реально конечный набор
возможных значение. Считает быстрее, массивы компактнее.
Цена меняется в конечных пунтах.
Рустам TradeInWest.ru, если пишешь робота, то цена — double или decimal. Если прогу для оптимизации и тестирования стратегий, то только int. В последнем случае надо предварительно умножить цену, чтоб точность не потерять — для ES mini например надо цену на 100 умножать, ну и комиссию и проскальзывание соот-но учесть нужную.
avatar
Тунеядец, ну собственно как вариант я это и прописал выше:
«или ты цены всегда умножаешь на какой-то множитель, чтобы было целым?»

но если честно — не вижу в этом смысла большого
Используй decimal, забей на long
avatar
Андрей Коган, его int смущает.
Рустам TradeInWest.ru, ну по-любому надо конвертировать из одного типа в другой
в данном случае я бы так делал:

int a = 300;
int b = 400;
decimal c = (decimal)a * (decimal)b;
avatar
Андрей Коган, переменные из массива.
Памяти нажрёт decimal.
Ну и считает поди чуть-чуть медленнее.
Андрей Кучумов, дык с современными компьютерами разница будет не видна.
Для финансовой сферы рекомендуется использовать decimal.
avatar
Тунеядец, большое спасибо!
Андрей Кучумов, незачто — обращайтесь ещё.
avatar

теги блога Андрей Кучумов

....все тэги



UPDONW
Новый дизайн