#c# #.net
#c# #.net
Вопрос:
У меня есть 6-значное целое число, скажем, «153060», которое я хотел бы разделить на
int a = 15 (первые 2 цифры),
int b = 30 (вторые 2 цифры),
int c = 60 (третьи 2 цифры),
Первое, что приходит на ум, это преобразовать int в строку, разделить его с помощью SubString (или варианта), а затем преобразовать обратно в int .
Однако это кажется крайне неэффективным способом сделать это. Кто-нибудь может порекомендовать лучший / более быстрый способ решения этой проблемы?
Спасибо!
Дополнительная информация: причина разделения int заключается в том, что 6-значное целое число представляет HHMMSS, и я хотел бы использовать его для создания нового экземпляра DateTime:
DateTime myDateTime = новое время даты (год, месяц, день, a, b, c);
Однако пользовательское поле может принимать только целые числа.
Комментарии:
1. Почему время хранится с использованием представления base-10 в первую очередь, если это не строка?
2. Преждевременная оптимизация, корень всего зла.
3. Вам следует беспокоиться об эффективности, только если это будет частью массового процесса. например, происходит тысячи раз в секунду. В противном случае ваш описанный алгоритм работает нормально. (Старайтесь избегать преждевременной оптимизации, хотя в этом случае алгоритм / должен быть локализован. )
4. Вы также можете попробовать
DateTime.ParseExact(number.ToString(), "HHmmss")
, чтобы вам не понадобилосьSubString()
Ответ №1:
int y = number / 10000;
int m = (number - y*10000) / 100;
in d = number % 100;
Комментарии:
1. Вам нужно
int m = (number - (y * 10000)) / 100;
будет отредактировать: поймал это, прежде чем я смог указать на это!
Ответ №2:
Если ваша конечная цель — a DateTime
, вы можете использовать TimeSpan.ParseExact
для извлечения a TimeSpan
из строки, а затем добавить его в a DateTime
:
TimeSpan time = TimeSpan.ParseExact(time, "hhmmss", CultureInfo.InvariantCulture);
DateTime myDateTime = new DateTime(2011, 11, 2);
myDateTime = myDateTime.Add(time);
(Предполагается > = .NET 4)
Комментарии:
1. Да, но оно появляется только в .net 4.
2. Привет, Эндрю, я получаю сообщение об ошибке «System. TimeSpan не содержит определения для ‘ParseExact’.
3. Ах, это бы все объяснило 🙂
4. Да. Вы могли бы что-то сделать
DateTime.ParseExact
, но это, вероятно, было бы не так элегантно, как использованиеTimeSpan
: (
Ответ №3:
Как насчет чего-то подобного?
int i = 153060;
int a = i / 10000;
int b = (i - (a * 10000)) / 100;
int c = (i - ((a * 10000) (b * 100)));
Комментарии:
1. 1 для избежания модуля, который является довольно дорогостоящим по сравнению с вычитанием
2. @Cameron: Если вы собираетесь оптимизировать на этом уровне (что вряд ли будет полезно), вам следует полностью удалить деления.
3. @Joren: Ха, да, хороший момент (хотя я не вижу способа удалить деления в этом конкретном случае). Если по какой-то странной причине действительно требуется максимальная микрооптимизация, было бы, несомненно, быстрее, если бы входные данные были разделены на биты в первую очередь, поэтому понадобились бы только сдвиги и маски.
4. @Cameron: Деление на известную константу может быть заменено комбинацией сложений, сдвигов и умножений. Я не уверен, как далеко зайдет JIT с этим, но я знаю, что оптимизирующий компилятор C сделает некоторые сумасшедшие вещи. В качестве примера псевдокода uint64 y = x; y *= 0x11111111; y = x >> 3; y >>= 34; return (uint32)y; вернет x / 60, если x также является 32-разрядным целым числом без знака.
5. @Cameron: В любом случае, я бы просто написал модуль, поскольку это то, что представляет то, чего я пытаюсь достичь наиболее очевидно. Если это окажется недостаточно быстрым, только тогда я бы подумал о том, чтобы сделать это менее очевидным способом.
Ответ №4:
Вы можете сделать это без преобразования в строку с помощью:
int a = 153060 / 10000;
int b = (153060 / 100) % 100;
int c = 153060 % 100;
Я не уверен, насколько это эффективно по сравнению с преобразованием в строку. Я думаю, что это всего лишь 4 операции. Так что это может быть быстрее.