1.Введение
Чтобы найти образец машинного кода 3->2, я разработал несколько программ для выполнения вычислений. Программы могут сэкономить больше времени и генерировать более точные результаты для дальнейших исследований. Две основные программы используются для преобразования целого числа в код и преобразования кода в целое число, а другая программа представляет собой сильно завершенную версию, основанную на этих двух. У этого есть больше функций, которые все способствуют исследованию, например, вычисление значения кода в квадрате или обратного кода. Далее я приведу подробности этих программ и результаты программных исследований.
2.Основная идея преобразования целого числа
Для любого кода мы сначала разбиваем его на массив строк. В каждом индексе массива есть только 1 цифра. Длина массива равна длине кода.
Ex: 21011
number 2,1,0,1,1 index 0,1,2,3,4
Затем, поскольку каждая цифра в 1,5 раза больше цифры справа, мы можем вычислить значение всего кода следующим образом:
number 2,1,0,1,1 index 0,1,2,3,4 value 2*(1.5^4),1*(1.5^3),0*(1.5^2),1*(1.5^1),1*(1.5^0)
Степень 1,5 — это длина кода минус индекс, затем минус 1. Мы используем цикл for, чтобы сложить значение каждой цифры, а затем получить сумму.
double sum=0 for(int i=0;i<c.length;i++){ sum+=c[i]*(Math.pow(1.5,c.length-i-1)); } Result:16
В этом случае 21011-> 2*5,0625+1*3,375+0+1,5+1=16.
Программа позволяет выводить нецелочисленные значения, но это хорошо для исследований.
3.Основная идея целочисленного кода:
Для любого целого числа мы используем рекурсивную функцию для преобразования его в код. В базовом случае, когда число равно 0,1,2, просто возьмите число в качестве кода. Рекурсивный случай: когда число ›=3, по модулю числа на 3 и взять остаток в качестве кода, а затем умножить оставшуюся часть на 2/3 в качестве нового числа. Делайте рекурсивный случай, пока код не станет меньше 3.
Вот пример числа 19.
19mod3=1, 19-1=18, 18*2/3=12 12mod3=0, 12-0=12, 12*2/3=8 8mod3=2, 8-2=6, 6*2/3=4 4mod3=1, 4-1=3, 3*2/3=2 2mod3=2, 2-2=0
Код: 21201 (возьмем результат первого столбца снизу вверх)
ArrayList<Integer> code=new ArrayList<>(); code.add(num%3); while(num>=3){ num=(num-num%3)*2/3; code.add(num%3); }
Программа использует ArrayList для хранения цифр кода, чтобы сделать его динамичным и связным. Поскольку порядок в ArrayList обратный, мы используем цикл for для печати кода.
for(int i=code.size()-1;i>=0;i--){ System.out.print(code.get(i));
4.Квадратный код
Это функция для возведения кода в квадрат и сохранения типа кода как String (для удобства преобразования в целое число).
public static String Square(String code){ long sq=Integer.parseInt(code); sq=sq*sq; String s=Long.toString(sq); return s; }
Если мы хотим получить значение квадрата кода целого числа a, мы используем вложенную функцию ниже. Сначала мы преобразуем его в код (тип String), затем возводим его в квадрат и сохраняем как String, а затем преобразуем обратно в целое число.
toInt(Square(toCode(a)))
Полный функциональный сегмент toCode() и toInt():
public static double toInt(String code){ String[] s=code.split(""); int[] nums=new int[s.length]; for(int i=0;i<s.length;i++){ nums[i]=Integer.parseInt(s[i]); } double sum=0; for(int i=0;i<nums.length;i++){ sum+=nums[i]*(Math.pow(1.5,nums.length-i-1)); } return sum; }//code to integer public static String toCode(int num){ String code=""; code=code+String.valueOf(num%3); while(num>=3){ num=(num-num%3)*2/3; code=code+String.valueOf(num%3); } char[] ch = code.toCharArray(); String reverse=""; for(int i=ch.length-1;i>=0;i--){ reverse+=ch[i];} return reverse; }//integer to code
Для оперативности исследования я также предусмотрел две функции для печати кода от 1 до числа или от числа до другого числа. Они основаны на функции toCode(), но используют массив для хранения данных. У них одинаковое имя функции, но разное количество аргументов.
public static void printCode(int size){ String codes[] = new String[size+1]; for(int i=0;i<size+1;i++){ codes[i]=toCode(i); } for(int i=0;i<size+1;i++){ System.out.print(i+","); System.out.println(codes[i]); } }//print code from 0 to a number public static void printCode(int start,int end){ String codes[] = new String[end-start+1]; for(int i=start;i<end+1;i++){ codes[i-start]=toCode(i-start); } for(int i=start;i<end+1;i++){ System.out.print(i+","); System.out.println(codes[i-start]); } }//print code between two numbers
Теперь все необходимые функции настроены. Вот результат получения значения квадрата кода первых 50 чисел.
1->1 2->4 3->9 4->16 5->25 6->36 7->49 8->64 9->81 10->100 11->121 12->144 13->169 14->124.28125 15->225 16->256 17->245.96875 18->324 19->361 20->356.96875 21->279.6328125 22->250.9140625 23->276.7890625 24->576 25->625 26->611.453125 27->729 28->784 29->841 30->803.1796875 31->821.1484375 32->819.6015625 33->564.556640625 34->588.525390625 35->628.837890625 36->1296 37->1369 38->1444 39->1375.76953125 40->1454.76953125 41->1438.94921875 42->1764 43->1849 44->1839.1796875 45->1807.154296875 46->1801.333984375 47->1851.302734375 48->1844.103515625 49->1876.556640625 50->1816.580078125
Некоторые из них возвращали число в квадрате, которое в точности равно квадрату исходного числа. Однако числа 14,17,20,21,22,23,26,30,31,32,33,34,35,39,40,41,44,45,46,47,48,49,50 не не применять правило «Квадрат кода возвращает число в квадрате». Причина в том, что когда мы возводим в квадрат код этих чисел, во время вычисления возникает цифра переноса.
Например, 14, если мы возведем в квадрат код числа 14 (2122) и запишем вычисление таким образом, в результате появится число «12». Для десятичной системы нам нужно поднять 12 и получить результат 4502884, а не 449–12–884.
Нет определенной закономерности между числом с применением правила квадрата или не применяется, но есть больше чисел, когда правило не применяется, когда мы увеличиваем число.
5.Обратный код
Обратный код — самая сложная и интересная часть исследования. Функция toReverse() предназначена для преобразования кода в обратный код (например, 21011-›11012) и сохранения его типа String. Основная программа, расположенная ниже функции, используется для вывода всех чисел, у которых ее обратный код меньше исходного кода, деленного на число N. Число N является критерием исследования обратного кода. Также эта программа подсчитает, сколько чисел удовлетворяет значению N.
public static String toReversed(int num){ String code=""; code=code+String.valueOf(num%3); while(num>=3){ num=(num-num%3)*2/3; code=code+String.valueOf(num%3); } return code; } public static void main(String args[]){ int count=0; for(int i=0;i<1000;i++){ double rev=toInt(toReversed(i)); if(rev<(i/N)){//experiment with this number count++; System.out.print(i+" "); } } System.out.print(count);
Во-первых, я устанавливаю N в разные значения и наблюдаю за разнообразием счетчиков. Когда N меньше 0,606, в списке 999 номеров. Это означает, что все значение обратного кода меньше значения исходного кода, деленного на 0,606. Когда N больше 22,305, в списке нет чисел. Когда N равно 1,348, в списке ровно 500 кодов.
Позже я рисую график и использую интеграл для представления распределения чисел. Площадь слева от 1,348 и справа от 1,348 одинакова, а максимальное значение f(x) равно 1,06, что означает, что при N=1,06 количество чисел в списке менялось быстрее всего. Однако это не нормальное распределение.
Другой шаблон: когда N равно 2,3,4,5, список чисел должен содержать все числа 3^N. В первой строке каждого списка я выделяю жирным шрифтом числа, соответствующие шаблону 3^N.
N=2: 9 15 18 24 27 36 42 45 54 63 69 72 78 81 82 90 96 99 105 108 117 123 126 135 144 145 150 153 159 162 163 171 177 180 186 189 198 204 207 216 217 225 231 240 243 244 246 249 252 258 261 267 270 271 279 285 288 297 306 312 324 325 327 333 339 342 348 351 360 366 367 369 375 378 379 387 393 402 405 406 408 414 420 423 429 432 441 447 450 459 460 468 486 487 489 492 495 501 504 510 513 522 528 531 540 541 549 550 552 555 558 564 567 568 570 576 582 585 591 594 603 604 609 610 612 618 621 622 630 645 648 649 657 663 672 675 684 690 693 702 703 711 729 730 732 735 738 744 747 753 756 765 771 774 783 784 792 798 810 811 813 819 825 828 834 837 846 852 853 855 861 864 865 873 874 879 882 888 891 892 900 906 909 915 918 919 921 927 933 936 945 946 954 972 973 981 999 N=3: 27 36 54 63 81 108 117 123 135 144 162 189 216 225 243 270 279 297 306 324 360 366 369 378 387 405 432 459 468 486 513 522 540 549 567 603 609 612 621 630 648 675 690 702 729 730 738 756 765 783 792 810 825 828 837 846 852 855 864 873 891 906 915 918 927 933 945 972 N=4: 54 81 144 162 189 216 243 324 366 378 405 459 486 540 549 567 648 702 729 783 810 873 891 918 945 972 N=5: 81 216 243 324 405 459 486 549 567 648 729 810 945 972
Когда N становится все больше и больше, сначала исчезнут числа, не содержащие множителя 3, а затем числа, содержащие множитель 3, затем множитель 9, затем 27 и затем 81. Последние 3 числа — это 324, 486, 729, где 324 содержит множитель 3⁴, 486 содержит множитель 3⁵, а 729 само по себе является 3⁶. Причина, по которой это происходит, заключается в том, что если код делится на 3, он должен заканчиваться на 0. Если код делится на 9, он должен заканчиваться двумя нулями и так далее. Когда код заканчивается нулями, после реверсирования в нем должно быть меньше цифр, чем в исходном коде, потому что начальные нули ничего не значат. Тогда значение кода станет намного меньше исходного кода, и оно появится в списке, когда N станет очень большим.
Наконец, самое интересное, что есть 11 кодов-палиндромов, исходный код которых равен обратному коду. 11 чисел:
0,1,2,5,8,17,35,170,278,422,494
Число 494 — единственное, которое имеет более 1 цифры и само по себе является палиндромом. Поздравляем 494!