Как получить первую цифру в int (C #)?
В С#, как лучше всего получить 1-ю цифру в int? Метод, который я придумал, состоит в том, чтобы превратить int в строку, найти 1-й символ строки, а затем вернуть его обратно в int.
Хотя это работает, кажется, что есть хорошее, простое, основанное на математике решение такой проблемы. Манипуляции со строками кажутся неуклюжими.
Редактировать: независимо от разницы в скорости, mystring[0] вместо Substring() по-прежнему просто манипулирует строкой
задан 31 марта ’09, 12:03
Это даже медленнее, чем рекурсивный метод. знак равно J. Steen
мой плохой, я забыл сбросить секундомер =), он действительно медленнее, чем другие — Quan Mai
Это не удастся на отрицательных числах. — plinth
первая цифра int всегда равна 1 с нулевым подавлением (01010101010100101011011011100101) LOL — Zachary Scott
25 ответы
и i будет содержать то, что вам нужно
ответ дан 22 апр.
тесты
Во-первых, вы должны решить, что вы подразумеваете под «лучшим» решением, конечно, принимая во внимание эффективность алгоритма, его удобочитаемость/сопровождаемость и вероятность появления ошибок в будущем. Однако тщательные модульные тесты обычно позволяют избежать этих проблем.
Я запускал каждый из этих примеров 10 миллионов раз, и значение результата равно количеству ElapsedTicks что прошло.
Без лишних слов, от самого медленного к самому быстрому, алгоритмы таковы:
Преобразование в строку, взять первый символ
Использование логарифма
петля
Conditionals
Развернутый и оптимизированный цикл
Примечание:
каждый тестовый вызов Random.Next() получить следующий int
ответ дан 31 мар ’09, в 20:03
Прогнали их на каком наборе целых чисел? — mqp
Это оооочень банально. Я ценю то, что вы сделали, и это довольно информативно, но это слишком много для 99% приложений. Боюсь, у некоторых начинающих программистов может сложиться плохое впечатление. (жесткая, преждевременная оптимизация над удобочитаемостью) Тем не менее, это все еще весело. 🙂 — Саманта Бранхам
+1 за тесты, но я согласен, что это перебор. Если вы ЭТО беспокоитесь о производительности, вам, вероятно, не следует использовать C # в первую очередь 🙂 — Грэм С
+1 — Отличный материал. Это своего рода позолоченная роскошная модель, которая просто делает очевидным, что вы любите программировать. Большое вам спасибо. И нет, Стюарт, я не думаю, что это загрязнит умы ничего не подозревающих новичков. Надеюсь, это научит их любить программное обеспечение. — Марк Бриттингем
@Vikash — кастинг char к int оценивается как кодовая точка символа, поэтому приведение символа 0 оценивается как 48. Вычитание 48 эффективно выполняет преобразование в целое число. В качестве другого примера, кастинг персонажа 5 к int оценивается как 53, и вычитание из него 48 дает 5. — Джон Раш
РЕДАКТИРОВАТЬ
Несколько человек запросили петлевую версию
ответ дан 31 мар ’09, в 16:03
Рекурсия для чего-то подобного. Позор вам. Вставьте туда петлю. — Велбог
@Welbog 🙂 Обычно я бы так и сделал. Но у меня много ностальгии по этому конкретному вопросу. Это почти первые вопросы, которые мне задавали для задания по CS. В то время я написал по существу это решение. — ДжаредПар
Это тот случай, когда «хорошо» = медленно — Келтекс
Я надеюсь, что оптимизатор увидит первую версию как нечто, что можно оптимизировать с помощью хвостового вызова, и в этом случае она не будет медленнее. — Rmeador
Но, @Jared, вычитание последней цифры здесь совершенно не нужно. Просто разделите на 10. — Конрад Рудольф
Лучшее, что я могу придумать, это:
Вы можете избежать ненужных преобразований между целыми и двойными числами, используя divisor=Convert.ToInt32(Math.Pow(10, Math.Floor(Math.Log10(value))))); firstDigit = значение/делитель; — Мартин Штеттнер
К сожалению, это не работает, когда значение равно 1 (возвращает 0) или если значение отрицательно. Исправление: int numberOfDigits = 1 + Convert.ToInt32(Math.Floor(Math.Log10(Math.Abs(value))))); — ДАНДАН
вариант ответа Антона:
ответ дан 31 мар ’09, в 16:03
Я думаю, я бы просто оставил это на /10 и /1000 . Вы по-прежнему получаете преимущество более агрессивного разделения, но с немного меньшим беспорядком. +1 за творчество 🙂 — Саманта Бранхам
Напоминает мне функцию в bcl, которую кто-то обнаружил, метод был довольно уродливым для чтения, но в основном он выполнял циклические сравнения и группировал сравнения в группы по десять или около того, зная, что современный процессор сможет лучше обрабатывать группу сравнивает за раз. — средний код
Это просто фантастически уродливо, потому что C# не имеет способа генерировать эти константы во время компиляции (и делать это во время выполнения было бы дороже, чем то, что вы пытаетесь предотвратить). В таком языке, как Lisp, где вы контролируете расчетное время, быстрый и элегантный способы одинаковы. 🙂 — Ken
Развертывание цикла, безусловно, лучше, чем куча дерьмовых операторов if/else. Это элегантно и исполнитель. — Рандольфо
если вы сделаете первое «если» «пока», оно также работает с 64-битными (но еще «уродливее»). +1 — Мартин Штеттнер
ответ дан 31 мар ’09, в 15:03
Разве это не идентично тому, что я написал? Он просто использует [] вместо Substring — Дина
Нет: он возвращает символ, а не строку, и поиск [] должен быть быстрее — Джоэл Кохорн
Это правда, но это все тот же базовый метод — разбор строкового представления. Я думаю, что @Dinah ищет что-то. знаете. другое. — Рандольфо
@Randolpho: точно. Извините, если я был неясен об этом. Я обновил вопрос, чтобы уточнить. — Дина
Я также вернул бы firstDigit-‘0’, чтобы получить int. (это работает в c. я думаю, что это работает в c#) — Николас Ирисарри
Имел ту же идею, что и Леннарт
Это также работает с отрицательными числами.
ответ дан 31 мар ’09, в 16:03
Если вы думаете, что ответ Keltex уродлив, попробуйте этот, он ДЕЙСТВИТЕЛЬНО уродлив и даже быстрее. Он выполняет развернутый бинарный поиск для определения длины.
PS У Мартина Стеттнера была такая же идея.
ответ дан 31 мар ’09, в 19:03

@Rasch: Ах, восторг! Его нужно спрятать, выносить только по особым случаям и читать шепотом. Кто сказал, что у программирования нет души? — Майк Данлэйви
как насчет i=(. moreugly. )i>=100?i>=1000?i/1000:i/100:i>=10?i/10:i; — Дэвид Мердок
Очевидный, но медленный математический подход:
ответ дан 31 мар ’09, в 16:03

Время это, это не должно быть медленным на всех. Это должно было быть моим предложением, и, учитывая, что это чисто математическое решение без циклов, оно, возможно, быстрее, чем многие решения здесь. Имейте в виду, что каждый процессор x86, продаваемый сегодня, имеет очень, очень быстрый процессор с плавающей запятой. — Адам Дэвис
Я думаю, вам действительно следует использовать Math.Log10 здесь — Мартин Штеттнер
Спасибо, Мартин. Я редко пользуюсь математическими библиотеками .NET и забыл, что это Log и Log10 вместо Log и Ln. — mqp
Ну, Адам, по крайней мере, он должен принимать 10 ^ (N-1) (где n — количество цифр) плюс он должен принимать логарифм. По сравнению с циклическим ответом (где вы делите N — 1 раз) мне кажется, что он должен быть хотя бы немного медленнее. Но меня регулярно удивляют тесты, так что кто знает. — mqp
Кроме того, ОП запросил более осмысленное выражение без учета производительности, и это самый прямой (математический) способ выразить то, что ищется. — Харпо
Результат в temp
ответ дан 01 апр.
@ck: Какое округление выдано? Деление в данном случае целочисленное, каждое деление точно отсекает последнюю цифру. — Мартин Штеттнер
Я знаю, что это не С#, но удивительно любопытно, что в python «получить первый символ строкового представления числа» быстрее!
РЕДАКТИРОВАТЬ: нет, я ошибся, я забыл снова построить int, извините. Развернутая версия самая быстрая.
ответ дан 22 апр.
Но преобразует ли он его обратно в целое число? — Самуил
упс, теперь это имеет смысл -.- — зет
ну, он мог бы сказать, что это был IronPython, чтобы сделать это немного менее не по теме — Ravi
Я только что наткнулся на этот старый вопрос и почувствовал склонность предложить другое предложение, поскольку ни один из других ответов пока не дает правильного результата для все возможные входные значения, и это все еще можно сделать быстрее:
Это работает для всех целых значений со знаком включительно -2147483648 которое является наименьшим целым числом со знаком и не имеет положительного аналога. Math.Abs( -2147483648 ) запускает System.OverflowException и — -2147483648 вычисляет -2147483648 .
Реализация может рассматриваться как комбинация преимуществ двух самых быстрых реализаций на данный момент. Он использует бинарный поиск и избегает лишних делений. Быстрый тест с индексом цикла со 100,000,000 XNUMX XNUMX итераций показывает, что он в два раза быстрее, чем самая быстрая на данный момент реализация.
Это заканчивается после 2,829,581 клещи.
Для сравнения я также измерил исправленный вариант самой быстрой на данный момент реализации, которая заняла 5,664,627 клещи.
Принятый ответ с той же необходимой коррекцией 16,561,929 галочки для этого теста на моем компьютере.
Простые функции, подобные этим, можно легко проверить на правильность, поскольку итерация всех возможных целочисленных значений занимает не более нескольких секунд на текущем оборудовании. Это означает, что менее важно реализовать их в исключительно читабельной форме, поскольку позже просто не будет необходимости исправлять внутри них ошибку.
Как вы можете получить первую цифру в int (C #)?
В С#, какой лучший способ получить 1-ю цифру в int? Метод, который я придумал, состоит в том, чтобы превратить int в строку, найти 1-ю строку char строки, а затем вернуть ее обратно к int.
В то время как это выполняет эту работу, похоже, что существует такая проблема, как хорошее, простое математическое решение этой проблемы. Строгое манипулирование кажется неуклюжим.
Изменить:, независимо от разницы в скорости, mystring [0] вместо Substring() все еще просто манипулирует строкой
25 ответов
и i будут содержать то, что вам нужно
Бенчмарки
Во-первых, вы должны решить, что вы подразумеваете под «лучшим» решением, конечно, это учитывает эффективность алгоритма, его читаемость/ремонтопригодность и вероятность появления ошибок в будущем. Однако тщательные модульные тесты могут вообще избежать этих проблем.
Я запускал каждый из этих примеров 10 миллионов раз, а значение результата — это число ElapsedTicks , которое прошло.
Без дальнейших шуток, от самых медленных до самых быстрых, алгоритмы:
Преобразование в строку принимает первый символ
Использование логарифма
Циклическое
Conditionals
Развернутый и оптимизированный цикл
Примечание:
каждый тест вызывает Random.Next() , чтобы получить следующий int
10 проверок. просто изменив порядок чеков, мы можем сделать это намного быстрее
15 циклов, в то время как прогнозируемый скачок составляет 0,5-1 цикла в зависимости от процессора
EDIT
Несколько человек запросили версию цикла
Лучшее, что я могу придумать, это:
Не очень красиво:)
[Отредактировано: первый ответ был очень плохим:)]
[Редактировать 2: я бы, вероятно, советовал решениям, управляющим строкой)
[Редактировать 3: форматирование кода приятно:)]
вариант ответа Антона:
Имел ту же идею, что и Lennaert
Это также работает с отрицательными числами.
Если вы считаете, что ответ Keltex уродлив, попробуйте это, он ДЕЙСТВИТЕЛЬНО некрасиво и даже быстрее. Он разворачивает двоичный поиск, чтобы определить длину.
P.S. У MartinStettner была та же идея.
Я просто наткнулся на этот старый вопрос и почувствовал склонность предлагать другое предложение, так как ни один из других ответов до сих пор не возвращает правильный результат для всех возможных входных значений, и он все равно может быть выполнен быстрее:/p >
Это работает для всех значащих целочисленных значений inclusive -2147483648 , который является наименьшим знаковым целым и не имеет положительного аналога. Math.Abs( -2147483648 ) запускает a System.OverflowException и — -2147483648 вычисляет -2147483648 .
Реализация может рассматриваться как комбинация преимуществ двух самых быстрых реализаций. Он использует двоичный поиск и избегает лишних делений. Быстрый тест с индексом цикла с 100 000 000 итераций показывает, что он в два раза быстрее, чем самая быстрая реализация.
Он заканчивается после 2,829,581 тиков.
Для сравнения я также измерил скорректированный вариант самой быстрой реализации, которая занимала 5,664,627.
Принятый ответ с той же самой коррекцией потребовал 16,561,929 тиков для этого теста на моем компьютере.
Простые функции, подобные этим, могут быть легко доказаны для правильности, так как итерация всех возможных значений целых чисел занимает не более нескольких секунд на текущем оборудовании. Это означает, что менее важно реализовать их в исключительно читабельном виде, поскольку в дальнейшем их не будет вообще исправлять ошибку.
Подскажите как найти первую (последнюю) цифру числа (с++)
число целое, не указано это двух цифровое, трех цифровое или пяти цифровое.. . так что деление и остатки не прокатят.
Вадим, мне потом их суммировать нужно, не прокатит

прокатит и деление и остатки: http://ideone.com/Nd7wMc
Преобразуйте в char* возьмите первый и последний байт, преобразуйте обратно в цифры.
1. Преобразовать число в строку (IntToStr)
2. Узнать количество символов в строке (length)
3. Взять первый и последний символ (str[])
4. Преобразовать обратно в число (StrToInt)

число % 10 вернёт остаток от деления на десять. конкретно — последняя цифра.
а первую цифру — в цикле ищи.
число >=10. число = (int) число/10;
в результате в числе будет только старший разряд числа
int funct(int number)
<
int digit1,digit2;
digit1=number (знак процента) 10;
if(number>=10)
number=number/10
digit2=number;
return digit1+digit2;
>
ёбанный движёк мэйла
Как вывести первую цифру числа в c
БлогNot. C++: извлечь любую цифру из числа
C++: извлечь любую цифру из числа
При нумерации цифр числа справа налево, начиная с единицы, для извлечения из натурального числа n цифры под номером d достаточно выполнить код вида n%10 d /10 d-1
Пример законченного приложения (демка, код не «экономичный»):
Ну а «извлечь из целого числа все цифры по порядку» — задача очень простая, и решить можно множеством способов, например: