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!