Количество цифр в целом в Java
Изучите различные способы получения количества цифр в целом в Java.
- Автор записи
1. введение
В этом кратком руководстве мы рассмотрим различные способы получения количества цифр в целочисленном в Java.
Мы также проанализируем эти различные методы и выясним, какой алгоритм лучше всего подходит для нашей ситуации.
Дальнейшее чтение:
Как округлить число до N десятичных знаков в Java
Проверьте, является ли строка Числовой в Java
Практическое руководство по десятичному формату
2. Количество цифр в целочисленном числе
Для методов, обсуждаемых здесь, мы рассматриваем только положительные целые числа. Если мы ожидаем каких-либо отрицательных входных данных, то мы можем сначала использовать Math.abs(число) перед использованием любого из этих методов.
2.1. Решение На основе строк
Возможно , самый простой способ получить количество цифр в Integer – это преобразовать его в String и вызвать метод length () . Это вернет длину Строки представления нашего числа:
Но это может быть неоптимальным подходом, так как этот оператор включает выделение памяти для строки для каждой оценки . JVM должен сначала проанализировать наш номер и скопировать его цифры в отдельную Строку , А также выполнить ряд различных операций (например, сохранение временных копий, обработка преобразований Юникода и т. Д.).
Если у нас есть только несколько чисел для оценки, то мы можем явно пойти с этим решением – потому что разница между этим и любым другим подходом будет пренебрегаться даже для больших чисел.
2.2. Логарифмический Подход
Для чисел, представленных в десятичной форме, если мы возьмем их логин в базе 10 и округлим его, то получим количество цифр в этом числе:
Обратите внимание, что log 10 0 какого-либо числа не определено. Итак, если мы ожидаем каких-либо входных данных со значением 0 , тогда мы можем проверить и это.
Логарифмический подход значительно быстрее, чем подход на основе String , поскольку ему не нужно проходить процесс преобразования данных. Это просто включает в себя простой, простой расчет без какой-либо дополнительной инициализации объекта или циклов.
2.3. Повторное Умножение
В этом методе мы возьмем временную переменную (инициализированную в 1) и будем непрерывно умножать ее на 10, пока она не станет больше нашего числа. Во время этого процесса мы также будем использовать переменную length , которая будет отслеживать длину числа:
В этом коде строка temp совпадает с записью temp = (temp << 3) + (temp << 1) . Поскольку умножение обычно является более дорогостоящей операцией на некоторых процессорах по сравнению с операторами сдвига, последние могут быть немного более эффективными.
2.4. Деление на две степени
Если мы знаем о диапазоне нашего числа, то мы можем использовать вариацию, которая еще больше сократит наши сравнения. Этот метод делит число на степени двух (например, 1, 2, 4, 8 и т. Д.):
Этот метод делит число на степени двух (например, 1, 2, 4, 8 и т. Д.):
Он использует тот факт, что любое число может быть представлено сложением степеней 2. Например, 15 можно представить в виде 8+4+2+1, которые все являются степенями 2.
Для 15-значного числа мы бы провели 15 сравнений в нашем предыдущем подходе, который мы сократили до 4 в этом методе.
2.5. Разделяй и властвуй
Это, возможно, самый громоздкий подход по сравнению со всеми другими, описанными здесь, но излишне говорить, этот самый быстрый , потому что мы не выполняем никакого типа преобразования, умножения, сложения или инициализации объекта.
Мы получаем наш ответ всего в трех или четырех простых утверждениях if :
Подобно предыдущему подходу, мы можем использовать этот метод только в том случае, если мы знаем о диапазоне нашего числа.
3. Бенчмаркинг
Теперь, когда у нас есть хорошее понимание потенциальных решений, давайте проведем простой бенчмаркинг всех наших методов с использованием жгута Java Microbenchmark (JMH) .
В следующей таблице показано среднее время обработки каждой операции (в наносекундах):
Решение на основе String , которое является самым простым, также является самой дорогостоящей операцией, поскольку это единственная операция, которая требует преобразования данных и инициализации новых объектов.
Логарифмический подход значительно более эффективен по сравнению с предыдущим решением, поскольку он не требует преобразования данных. И, будучи однострочным решением, это может быть хорошей альтернативой подходу на основе String – .
Повторное умножение включает в себя простое умножение, пропорциональное длине числа; например, если число состоит из пятнадцати цифр, то этот метод будет включать в себя пятнадцать умножений.
Однако самый следующий метод использует тот факт, что каждое число может быть представлено степенями двух (подход, аналогичный BCD), и сводит то же самое к 4 операциям деления, поэтому он еще более эффективен, чем первый.
Наконец, как мы можем заключить, наиболее эффективным алгоритмом является многословная реализация “Разделяй и властвуй” , которая дает ответ всего в трех или четырех простых операторах if. Мы можем использовать его, если у нас есть большой набор данных чисел, которые нам нужно проанализировать.
4. Заключение
В этой краткой статье мы описали некоторые из способов найти количество цифр в целочисленном и сравнили эффективность каждого подхода.
Как посчитать количество цифр в числе java
In addition, this class provides several methods for converting an int to a String and a String to an int , as well as other constants and methods useful when dealing with an int .
Implementation note: The implementations of the «bit twiddling» methods (such as highestOneBit and numberOfTrailingZeros ) are based on material from Henry S. Warren, Jr.’s Hacker’s Delight, (Addison Wesley, 2002).
Field Summary
Constructor Summary
Method Summary
Methods declared in class java.lang.Object
Field Detail
MIN_VALUE
MAX_VALUE
BYTES
Constructor Detail
Integer
Integer
Method Detail
toString
If the radix is smaller than Character.MIN_RADIX or larger than Character.MAX_RADIX , then the radix 10 is used instead.
If the first argument is negative, the first element of the result is the ASCII minus character ‘-‘ ( ‘\u002D’ ). If the first argument is not negative, no sign character appears in the result.
The remaining characters of the result represent the magnitude of the first argument. If the magnitude is zero, it is represented by a single zero character ‘0’ ( ‘\u0030’ ); otherwise, the first character of the representation of the magnitude will not be the zero character. The following ASCII characters are used as digits:
toUnsignedString
If the radix is smaller than Character.MIN_RADIX or larger than Character.MAX_RADIX , then the radix 10 is used instead.
Note that since the first argument is treated as an unsigned value, no leading sign character is printed.
If the magnitude is zero, it is represented by a single zero character ‘0’ ( ‘\u0030’ ); otherwise, the first character of the representation of the magnitude will not be the zero character.
The behavior of radixes and the characters used as digits are the same as toString .
toHexString
The unsigned integer value is the argument plus 2 32 if the argument is negative; otherwise, it is equal to the argument. This value is converted to a string of ASCII digits in hexadecimal (base 16) with no extra leading 0 s.
The value of the argument can be recovered from the returned string s by calling Integer.parseUnsignedInt(s, 16) .
If the unsigned magnitude is zero, it is represented by a single zero character ‘0’ ( ‘\u0030’ ); otherwise, the first character of the representation of the unsigned magnitude will not be the zero character. The following characters are used as hexadecimal digits:
toOctalString
The unsigned integer value is the argument plus 2 32 if the argument is negative; otherwise, it is equal to the argument. This value is converted to a string of ASCII digits in octal (base 8) with no extra leading 0 s.
The value of the argument can be recovered from the returned string s by calling Integer.parseUnsignedInt(s, 8) .
If the unsigned magnitude is zero, it is represented by a single zero character ‘0’ ( ‘\u0030’ ); otherwise, the first character of the representation of the unsigned magnitude will not be the zero character. The following characters are used as octal digits:
toBinaryString
The unsigned integer value is the argument plus 2 32 if the argument is negative; otherwise it is equal to the argument. This value is converted to a string of ASCII digits in binary (base 2) with no extra leading 0 s.
The value of the argument can be recovered from the returned string s by calling Integer.parseUnsignedInt(s, 2) .
If the unsigned magnitude is zero, it is represented by a single zero character ‘0’ ( ‘\u0030’ ); otherwise, the first character of the representation of the unsigned magnitude will not be the zero character. The characters ‘0’ ( ‘\u0030’ ) and ‘1’ ( ‘\u0031’ ) are used as binary digits.
toString
toUnsignedString
parseInt
- The first argument is null or is a string of length zero.
- The radix is either smaller than Character.MIN_RADIX or larger than Character.MAX_RADIX .
- Any character of the string is not a digit of the specified radix, except that the first character may be a minus sign ‘-‘ ( ‘\u002D’ ) or plus sign ‘+’ ( ‘\u002B’ ) provided that the string is longer than length 1.
- The value represented by the string is not a value of type int .
parseInt
The method does not take steps to guard against the CharSequence being mutated while parsing.
parseInt
parseUnsignedInt
- The first argument is null or is a string of length zero.
- The radix is either smaller than Character.MIN_RADIX or larger than Character.MAX_RADIX .
- Any character of the string is not a digit of the specified radix, except that the first character may be a plus sign ‘+’ ( ‘\u002B’ ) provided that the string is longer than length 1.
- The value represented by the string is larger than the largest unsigned int , 2 32 -1.
parseUnsignedInt
The method does not take steps to guard against the CharSequence being mutated while parsing.
parseUnsignedInt
valueOf
In other words, this method returns an Integer object equal to the value of:
valueOf
In other words, this method returns an Integer object equal to the value of:
valueOf
byteValue
shortValue
intValue
longValue
floatValue
doubleValue
toString
hashCode
hashCode
equals
getInteger
The first argument is treated as the name of a system property. System properties are accessible through the System.getProperty(java.lang.String) method. The string value of this property is then interpreted as an integer value using the grammar supported by decode and an Integer object representing this value is returned.
If there is no property with the specified name, if the specified name is empty or null , or if the property does not have the correct numeric format, then null is returned.
In other words, this method returns an Integer object equal to the value of:
getInteger
The first argument is treated as the name of a system property. System properties are accessible through the System.getProperty(java.lang.String) method. The string value of this property is then interpreted as an integer value using the grammar supported by decode and an Integer object representing this value is returned.
The second argument is the default value. An Integer object that represents the value of the second argument is returned if there is no property of the specified name, if the property does not have the correct numeric format, or if the specified name is empty or null .
In other words, this method returns an Integer object equal to the value of:
getInteger
- If the property value begins with the two ASCII characters 0x or the ASCII character # , not followed by a minus sign, then the rest of it is parsed as a hexadecimal integer exactly as by the method valueOf(java.lang.String, int) with radix 16.
- If the property value begins with the ASCII character 0 followed by another character, it is parsed as an octal integer exactly as by the method valueOf(java.lang.String, int) with radix 8.
- Otherwise, the property value is parsed as a decimal integer exactly as by the method valueOf(java.lang.String, int) with radix 10.
The second argument is the default value. The default value is returned if there is no property of the specified name, if the property does not have the correct numeric format, or if the specified name is empty or null .
decode
The sequence of characters following an optional sign and/or radix specifier (» 0x «, » 0X «, » # «, or leading zero) is parsed as by the Integer.parseInt method with the indicated radix (10, 16, or 8). This sequence of characters must represent a positive value or a NumberFormatException will be thrown. The result is negated if first character of the specified String is the minus sign. No whitespace characters are permitted in the String .
compareTo
compare
compareUnsigned
toUnsignedLong
divideUnsigned
Note that in two’s complement arithmetic, the three other basic arithmetic operations of add, subtract, and multiply are bit-wise identical if the two operands are regarded as both being signed or both being unsigned. Therefore separate addUnsigned , etc. methods are not provided.
remainderUnsigned
highestOneBit
lowestOneBit
numberOfLeadingZeros
- floor(log2(x)) = 31 — numberOfLeadingZeros(x)
- ceil(log2(x)) = 32 — numberOfLeadingZeros(x — 1)
numberOfTrailingZeros
bitCount
rotateLeft
Note that left rotation with a negative distance is equivalent to right rotation: rotateLeft(val, -distance) == rotateRight(val, distance) . Note also that rotation by any multiple of 32 is a no-op, so all but the last five bits of the rotation distance can be ignored, even if the distance is negative: rotateLeft(val, distance) == rotateLeft(val, distance & 0x1F) .
rotateRight
Note that right rotation with a negative distance is equivalent to left rotation: rotateRight(val, -distance) == rotateLeft(val, distance) . Note also that rotation by any multiple of 32 is a no-op, so all but the last five bits of the rotation distance can be ignored, even if the distance is negative: rotateRight(val, distance) == rotateRight(val, distance & 0x1F) .
Программа на Java для подсчета количества цифр в целых числах
В этой программе вы научитесь считать количество цифр с помощью цикла while и for в Java.
Чтобы понять этот пример, вы должны знать следующие темы программирования Java:
- Типы данных Java (примитивные)
- Java while и do … while Loop
- Java для цикла
Пример 1. Подсчет количества цифр в целом числе с использованием цикла while
Вывод
В этой программе while цикл повторяется до тех пор, пока тестовое выражение не num != 0 будет оценено как 0 (ложь).
- После первой итерации число будет разделено на 10, и его значение будет 345. Затем счетчик увеличивается до 1.
- После второй итерации значение num будет 34, а счетчик увеличится до 2.
- После третьей итерации значение num будет 3, а счетчик увеличится до 3.
- После четвертой итерации значение num будет равно 0, а счетчик увеличится до 4.
- Затем тестовое выражение оценивается как ложное, и цикл завершается.
Примечание . Программа игнорирует любые нули перед числом. Следовательно, для таких цифр, как 000333, на выходе будет 3.
Пример 2: Подсчет количества цифр в целом числе с использованием цикла for
Вывод
В этой программе вместо использования цикла while мы используем цикл for без тела.
На каждой итерации значение num делится на 10, а значение count увеличивается на 1.
В for цикл завершается , когда num != 0 ложно, то есть Num = 0.
Поскольку for цикл не имеет тела, вы можете изменить его на один оператор в Java как таковой:
Сколько цифр в числе
Имеется натуральное число n . Как получить число цифр в этом числе?
Не надо никаких циклов, можно использовать логарифм
Для страховки можно использовать Math.ceil(Math.log10(x + 0.5))
Собственно, проверил и получил такие вот результаты (3 варианта вычисления: логарифм, деление, сдвиг):
- Логарифм работает за константное время и, согласен, не так уж быстро, как хотелось бы
- Сдвиг и деление работают линейно от длины числа, причем сдвиг примерно в пять раз быстрее деления.
- На десятизначных числах на long(это как раз порядка Integer.MAX_VALUE) логарифм так же быстр, как и сдвиг.
Вот, теперь можно почти точно сказать, что логарифм следует использовать только для long, и то, лишь с уверенностью, что будут меряться действительно длинные числа, больше десяти знаков.
Вот тестилка, можно и самим проверить, кто желает. На вход подается количество итераций.