From b66fa51e85b02b2edc6a36634588bbf61d725e62 Mon Sep 17 00:00:00 2001 From: thiflict <121az348@gmail.com> Date: Tue, 23 Jun 2026 08:33:47 +0500 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=BA=D0=BE=D0=BD=D0=B2=D0=B5=D1=80=D1=82=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D1=8F=20=D0=B8=D0=B7=20=D0=B4=D0=B5=D1=81=D1=8F?= =?UTF-8?q?=D1=82=D0=B8=D1=87=D0=BD=D1=8B=D1=85=20=D1=87=D0=B8=D1=81=D0=B5?= =?UTF-8?q?=D0=BB=20=D0=B2=20=D0=B4=D0=B2=D0=BE=D0=B8=D1=87=D0=BD=D1=8B?= =?UTF-8?q?=D0=B5.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/BinConvert.kt | 85 ++++++++++++++++ src/test/kotlin/BinConvertTest.kt | 160 ++++++++++++++++++++++++++++++ 2 files changed, 245 insertions(+) create mode 100644 src/main/kotlin/BinConvert.kt create mode 100644 src/test/kotlin/BinConvertTest.kt diff --git a/src/main/kotlin/BinConvert.kt b/src/main/kotlin/BinConvert.kt new file mode 100644 index 0000000..743742d --- /dev/null +++ b/src/main/kotlin/BinConvert.kt @@ -0,0 +1,85 @@ +package ru.thiflict.binaryutils + +/** + * Объект выполняет конвертации чисел из одной системы счисления в другую. + * + * Репозиторий: https://git.ds1.thiflict.ru/Thiflict/BinaryUtils + * + * @author Thiflict + * + * @since[1.0.3] + */ +object BinConvert { + + /** + * Преобразует значение типа [Long] в строку, представляющую его 64-битное двоичное представление. + * + * Биты выводятся от старшего (индекс 63) к младшему (индекс 0). Каждый бит представлен символом '0' или '1'. + * + * Результат всегда содержит ровно 64 символа, включая ведущие нули. + * + * @return строка длиной 64 символа, состоящая из нулей и единиц, соответствующая двоичному представлению числа. + */ + fun Long.toBinary(): String { + return (0..63) + .reversed() + .map { bit -> (this shr bit) and 1 } + .joinToString("") + } + + /** + * Преобразует значение типа [Int] в целое число, десятичная запись которого + * + * совпадает с 32-битным двоичным представлением исходного числа (включая ведущие нули). + * + * Биты перебираются от старшего (индекс 31) к младшему (индекс 0). + * + * Полученная строка из символов '0' и '1' интерпретируется как десятичное число. + * + * @return целое число, десятичное представление которого повторяет 32-битную двоичную форму исходного значения. + */ + fun Int.toBinary(): String { + return (0..31) + .reversed() + .map { bit -> (this shr bit) and 1 } + .joinToString("") + } + + /** + * Преобразует значение типа [Short] в целое число, десятичная запись которого + * + * совпадает с 16-битным двоичным представлением исходного числа (включая ведущие нули). + * + * Значение [Short] перед обработкой приводится к [Int]. Биты перебираются от старшего (индекс 15) + * + * к младшему (индекс 0). Полученная строка из '0' и '1' интерпретируется как десятичное число. + * + * @return целое число, десятичное представление которого повторяет 16-битную двоичную форму исходного значения. + */ + fun Short.toBinary(): Long { + return (0..15) + .reversed() + .map { bit -> (this.toInt() shr bit) and 1 } + .joinToString("") + .toLong() + } + + /** + * Преобразует значение типа [Byte] в целое число, десятичная запись которого + * + * совпадает с 8-битным двоичным представлением исходного числа (включая ведущие нули). + * + * Значение [Byte] перед обработкой приводится к [Int]. Биты перебираются от старшего (индекс 7) + * + * к младшему (индекс 0). Полученная строка из '0' и '1' интерпретируется как десятичное число. + * + * @return целое число, десятичное представление которого повторяет 8-битную двоичную форму исходного значения. + */ + fun Byte.toBinary(): Int { + return (0..7) + .reversed() + .map { bit -> (this.toInt() shr bit) and 1 } + .joinToString("") + .toInt() + } +} \ No newline at end of file diff --git a/src/test/kotlin/BinConvertTest.kt b/src/test/kotlin/BinConvertTest.kt new file mode 100644 index 0000000..dd4836e --- /dev/null +++ b/src/test/kotlin/BinConvertTest.kt @@ -0,0 +1,160 @@ +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import ru.thiflict.binaryutils.BinConvert.toBinary + + +class BinConvertTest { + + // ------------------- Long.toBinary() ------------------- + @Test + fun `Long toBinary zero`() { + val expected = "0".repeat(64) + assertEquals(expected, 0L.toBinary()) + } + + @Test + fun `Long toBinary positive one`() { + val expected = "0".repeat(63) + "1" + assertEquals(expected, 1L.toBinary()) + } + + @Test + fun `Long toBinary negative one`() { + val expected = "1".repeat(64) + assertEquals(expected, (-1L).toBinary()) + } + + @Test + fun `Long toBinary MAX_VALUE`() { + // Long.MAX_VALUE = 0x7FFFFFFFFFFFFFFF -> первый бит 0, остальные 63 бита 1 + val expected = "0" + "1".repeat(63) + assertEquals(expected, Long.MAX_VALUE.toBinary()) + } + + @Test + fun `Long toBinary MIN_VALUE`() { + // Long.MIN_VALUE = 0x8000000000000000 -> первый бит 1, остальные 63 бита 0 + val expected = "1" + "0".repeat(63) + assertEquals(expected, Long.MIN_VALUE.toBinary()) + } + + @Test + fun `Long toBinary arbitrary value`() { + // 123456789L = 0x75BCD15 -> двоичное представление из 64 бит + val expectedBinaryString = java.lang.Long.toBinaryString(123456789L).padStart(64, '0') + assertEquals(expectedBinaryString, 123456789L.toBinary()) + } + + // ------------------- Int.toBinary() ------------------- + @Test + fun `Int toBinary zero`() { + assertEquals("0".repeat(32), 0.toBinary()) + } + + @Test + fun `Int toBinary positive one`() { + assertEquals("0".repeat(31) + "1", 1.toBinary()) + } + + @Test + fun `Int toBinary negative one`() { + assertEquals("1".repeat(32), (-1).toBinary()) + } + + @Test + fun `Int toBinary MAX_VALUE`() { + // Int.MAX_VALUE = 0x7FFFFFFF -> 0 + 31 единица + assertEquals("0" + "1".repeat(31), Int.MAX_VALUE.toBinary()) + } + + @Test + fun `Int toBinary MIN_VALUE`() { + // Int.MIN_VALUE = 0x80000000 -> 1 + 31 ноль + assertEquals("1" + "0".repeat(31), Int.MIN_VALUE.toBinary()) + } + + @Test + fun `Int toBinary arbitrary value`() { + val value = -987654321 + val expected = Integer.toBinaryString(value).padStart(32, '0') + assertEquals(expected, value.toBinary()) + } + + // ------------------- Short.toBinary() ------------------- + @Test + fun `Short toBinary zero returns Long`() { + // бинарная строка из 16 нулей -> Long = 0 + assertEquals(0L, (0).toShort().toBinary()) + } + + @Test + fun `Short toBinary positive one`() { + // "0000000000000001" -> 1L + assertEquals(1L, (1).toShort().toBinary()) + } + + @Test + fun `Short toBinary negative one`() { + // "1111111111111111" -> 1111111111111111L + assertEquals(1111111111111111L, (-1).toShort().toBinary()) + } + + @Test + fun `Short toBinary MAX_VALUE`() { + // 0x7FFF -> "0111111111111111" -> 111111111111111L (15 единиц) + assertEquals(111111111111111L, Short.MAX_VALUE.toBinary()) + } + + @Test + fun `Short toBinary MIN_VALUE`() { + // 0x8000 -> "1000000000000000" -> 1000000000000000L + assertEquals(1000000000000000L, Short.MIN_VALUE.toBinary()) + } + + @Test + fun `Short toBinary arbitrary positive`() { + // 12345 = 0x3039 -> binary: 0011000000111001 + val expected = "0011000000111001".toLong() // 11000000111001 -> 11000000111001L? Actually leading zeros are ignored. + // "0011000000111001" -> decimal 11000000111001? Let's compute: 0011000000111001 -> 11000000111001 (14 digits) = 11,000,000,111,001? Wait, the string is 16 chars: 0011000000111001. + // toLong will parse as decimal: 11000000111001? The leading zeros don't change the numeric value. + // The result: 0011000000111001 as decimal is 11000000111001? Let's count: after removing leading zeros, string is "11000000111001" which is 11,000,000,111,001? Actually "11000000111001" is 14 digits: 11 trillion something. + // But it's easier to build directly: val expected = "0011000000111001".toLong() works. + assertEquals("0011000000111001".toLong(), (12345).toShort().toBinary()) + } + + // ------------------- Byte.toBinary() ------------------- + @Test + fun `Byte toBinary zero returns Int`() { + assertEquals(0, (0).toByte().toBinary()) + } + + @Test + fun `Byte toBinary positive one`() { + // "00000001" -> 1 + assertEquals(1, (1).toByte().toBinary()) + } + + @Test + fun `Byte toBinary negative one`() { + // "11111111" -> 11111111 + assertEquals(11111111, (-1).toByte().toBinary()) + } + + @Test + fun `Byte toBinary MAX_VALUE`() { + // 0x7F -> "01111111" -> 1111111 (7 единиц) + assertEquals(1111111, Byte.MAX_VALUE.toBinary()) + } + + @Test + fun `Byte toBinary MIN_VALUE`() { + // 0x80 -> "10000000" -> 10000000 + assertEquals(10000000, Byte.MIN_VALUE.toBinary()) + } + + @Test + fun `Byte toBinary arbitrary value`() { + // 42 = 0x2A -> "00101010" -> 101010 + assertEquals(101010, (42).toByte().toBinary()) + } +} \ No newline at end of file