-
Notifications
You must be signed in to change notification settings - Fork 13
/
math_big.go
1637 lines (1465 loc) · 54.9 KB
/
math_big.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
package main
import (
"fmt"
"math"
"math/big"
"math/rand"
"time"
)
func main() {
fmt.Println("----------big.Int()-----------")
// NewInt分配并返回一个新的Int设置为x。返回的是指针
BInt := big.NewInt(16)
FormatP(BInt)
BInt111 := big.NewInt(9)
// Sqrt将z设置为⌊√x⌋,即z²≤x的最大整数,并返回z。
//如果x为负数则表示恐慌。
//说白了就是设置z的值为x的开平方值,返回的是一个新的可以被接收的值,但是z一定会改变的
BInt_Sqrt := BInt.Sqrt(BInt111)
fmt.Println(BInt_Sqrt)
FormatP(BInt)
FormatP(BInt111)
//输出:
//*big.Int--16
//3
//*big.Int--3
//*big.Int--9
// Mod将y!= 0的z设置为模数x%y并返回z。
//如果y == 0,则会发生除以零的运行时恐慌。
// Mod实现欧几里得模数(不同于Go); 有关更多详细信息,请参见DivMod。
x := big.NewInt(16)
y := big.NewInt(9)
BInt_Mod := BInt.Mod(x, y)
fmt.Println()
fmt.Println(x)
fmt.Println(y)
fmt.Println(BInt_Mod)
fmt.Println(BInt)
//输出:
//16
//9
//7
//7
y = big.NewInt(9)
//将集合z加到x + y的总和并返回z。
BInt_Mod = BInt.Add(x, y)
BInt_Mod = BInt.Add(x, y)
fmt.Println()
fmt.Println(x)
fmt.Println(y)
fmt.Println(BInt_Mod)
fmt.Println(BInt)
//输出:
//16
//9
//25
//25
x = big.NewInt(16)
// Sub将z设置为差x-y并返回z。
BInt_Mod = BInt.Sub(x, y)
BInt_Mod = BInt.Sub(x, y)
fmt.Println(x)
fmt.Println(y)
fmt.Println(BInt_Mod)
fmt.Println(BInt)
//输出:
//16
//9
//7
//7
x = big.NewInt(16)
y = big.NewInt(9)
fmt.Println()
fmt.Println(x)
BInt_Mod = BInt.Div(x, y)
fmt.Println(BInt_Mod)
fmt.Println(BInt)
//输出:
//16
//9
//1
//1
x = big.NewInt(32)
y = big.NewInt(9)
m := big.NewInt(2)
// DivMod将z设置为商x div y,将m设置为模数x mod y,并返回y!= 0的对(z,m)。
// DivMod实现欧几里得除法和模数(与Go不同):
// q = x div y这样
// m = x-y * q,0 <= m <| y |
//(请参阅Raymond T.Boute,``函数div和mod的欧几里得定义''.ACM Transactions on Programming Languages and Systems(TOPLAS),14(2):127-144,New York,NY,USA, 4/1992。ACM出版社。)
//有关T划分和模数(如Go),请参见QuoRem。
BInt_DivMod_i, BInt_DivMod_m := BInt.DivMod(x, y, m) //不关m原来是多少,这里都将重新为他赋值为x%y
fmt.Println()
fmt.Println(x)
fmt.Println(y)
BInt_DivMod_i, BInt_DivMod_m := BInt.DivMod(x, y, m) //不关m原来是多少,这里都将重新为他赋值为x%y
fmt.Println(BInt_DivMod_m)
fmt.Println(BInt)
fmt.Println(m)
//输出:
//32
//9
//3
//5
//3
//5
x = big.NewInt(0b11001100)
y = big.NewInt(0b11001000)
// 0b11001000
//And设置z = x&y并返回z。
BInt_Mod = BInt.And(x, y)
fmt.Println()
fmt.Println(x)
fmt.Println(y)
fmt.Println(BInt_Mod)
BInt_Mod = BInt.And(x, y)
fmt.Println(0b11001000)
//输出:
//204
//200
//200
//200
//200
x = big.NewInt(0b11001100)
y = big.NewInt(0b11001000)
// ^y 0b00110111
// x 0b11001100
// x&^y 0b00000100
// AndNot设置z = x&^ y并返回z。
fmt.Println()
fmt.Println(x)
fmt.Println(y)
fmt.Println(BInt_Mod)
fmt.Println(BInt)
fmt.Println(0b00000100)
BInt_Mod = BInt.AndNot(x, y)
//204
//200
//4
//4
//4
x = big.NewInt(3)
y = big.NewInt(3)
m = big.NewInt(2)
// Exp set z = x ** y mod | m | (即,忽略m的符号),并返回z。
//如果m == nil或m == 0,则z = x ** y,除非y <= 0则z =1。如果m> 0,y <0,并且x和n不是相对质数,则z不变 然后返回nil。
//特定大小的输入的模幂不是密码恒定时间操作。
BInt_ret := BInt.Exp(x, y, m)
fmt.Println("x:", x)
fmt.Println("y:", y)
fmt.Println("m:", m)
fmt.Println("BInt_ret:", BInt_ret) //9除以2余数1
fmt.Println("BInt:", BInt)
//输出:
BInt_ret := BInt.Exp(x, y, m)
//y: 3
//m: 2
fmt.Println("x:", x)
fmt.Println("y:", y)
fmt.Println("m:", m)
fmt.Println("BInt_ret:", BInt_ret) //9除以2余数1
fmt.Println("BInt:", BInt)
BInt_ret = BInt.Abs(x)
fmt.Println()
fmt.Println("x:", x)
fmt.Println("BInt_ret:", BInt_ret)
fmt.Println("BInt:", BInt)
//输出:
//BInt_ret: 3
//BInt: 3
BInt_ret = BInt.Abs(x)
x = big.NewInt(3)
BInt = big.NewInt(2)
fmt.Println("x:", x)
fmt.Println("BInt_ret:", BInt_ret)
fmt.Println("BInt:", BInt)
//如果x> y则为+1
BInt_ret_int := BInt.Cmp(x)
fmt.Println()
fmt.Println("x:", x)
fmt.Println("BInt:", BInt)
BInt = big.NewInt(2)
BInt = big.NewInt(3)
BInt_ret_int = BInt.Cmp(x)
fmt.Println()
BInt_ret_int := BInt.Cmp(x)
fmt.Println("BInt_ret_int:", BInt_ret_int)
fmt.Println("BInt:", BInt)
fmt.Println("x:", x)
fmt.Println("BInt_ret_int:", BInt_ret_int)
fmt.Println("BInt:", BInt)
BInt = big.NewInt(3)
BInt_ret_int = BInt.Cmp(x)
fmt.Println("BInt_ret_int:", BInt_ret_int)
fmt.Println("BInt:", BInt)
fmt.Println("x:", x)
fmt.Println("BInt_ret_int:", BInt_ret_int)
fmt.Println("BInt:", BInt)
//BInt: 2
BInt = big.NewInt(4)
BInt_ret_int = BInt.Cmp(x)
//BInt_ret_int: 0
//BInt: 3
fmt.Println("x:", x)
fmt.Println("BInt_ret_int:", BInt_ret_int)
fmt.Println("BInt:", BInt)
//BInt: 4
y = big.NewInt(-3)
BInt = big.NewInt(2)
// CmpAbs比较x和y的绝对值并返回:
// 如果| x | <| y |返回-1,
// 如果| x |== | y |则为0,
// 如果| x | > | y |返回+1,
BInt_ret_int = BInt.CmpAbs(y)
fmt.Println()
fmt.Println("y:", y)
fmt.Println("BInt_ret_int:", BInt_ret_int)
BInt = big.NewInt(-3)
BInt = big.NewInt(2)
fmt.Println()
fmt.Println("y:", y)
fmt.Println("BInt_ret_int:", BInt_ret_int)
BInt_ret_int = BInt.CmpAbs(y)
BInt = big.NewInt(-4)
fmt.Println("y:", y)
fmt.Println("BInt_ret_int:", BInt_ret_int)
fmt.Println("BInt:", BInt)
fmt.Println("y:", y)
BInt = big.NewInt(-3)
BInt_ret_int = BInt.CmpAbs(y)
//输出:
//y: -3
fmt.Println("y:", y)
fmt.Println("BInt_ret_int:", BInt_ret_int)
fmt.Println("BInt:", BInt)
//y: -3
BInt = big.NewInt(-4)
BInt_ret_int = BInt.CmpAbs(y)
//
//y: -3
fmt.Println("y:", y)
fmt.Println("BInt_ret_int:", BInt_ret_int)
fmt.Println("BInt:", BInt)
//x = big.NewInt(0b00000010)
//x = big.NewInt(0b11000010)
x = big.NewInt(0b1100_0000_0000_0010) //中间可以用下划线进行分割
BInt = big.NewInt(3)
// Lsh设置z = x << n并返回z。
BInt_ret = BInt.Lsh(x, 2) //左移N位就相当于你x*2的N次方
fmt.Println()
fmt.Println("x:", x)
fmt.Println("BInt_ret:", BInt_ret) //9除以2余数1
fmt.Println("BInt:", BInt)
//0b00000010输出:
//x: 2
//BInt: 8
x = big.NewInt(0b1100_0000_0000_0010) //中间可以用下划线进行分割
//x: 194
//BInt_ret: 776
BInt_ret = BInt.Lsh(x, 2) //左移N位就相当于你x*2的N次方
//0b1100_0000_0000_0010输出:
fmt.Println("x:", x)
fmt.Println("BInt_ret:", BInt_ret) //9除以2余数1
fmt.Println("BInt:", BInt)
//x = big.NewInt(0b00000010)//右移会丢弃一些位
//x = big.NewInt(0b11000010)
x = big.NewInt(0b1100_0000_0000_0010) //中间可以用下划线进行分割
BInt = big.NewInt(3)
// Rsh设置z = x >> n并返回z。
BInt_ret = BInt.Rsh(x, 2) //左移N位就相当于你x*2的N次方
fmt.Println()
fmt.Println("x:", x)
fmt.Println("BInt_ret:", BInt_ret) //9除以2余数1
fmt.Println("BInt:", BInt)
//0b00000010输出:
//x: 2
//BInt_ret: 0
//BInt: 0
x = big.NewInt(0b1100_0000_0000_0010) //中间可以用下划线进行分割
//x: 194
//BInt_ret: 48
BInt_ret = BInt.Rsh(x, 2) //左移N位就相当于你x*2的N次方
//0b1100_0000_0000_0010输出:
fmt.Println("x:", x)
fmt.Println("BInt_ret:", BInt_ret) //9除以2余数1
fmt.Println("BInt:", BInt)
x = big.NewInt(2)
y = big.NewInt(3)
BInt = big.NewInt(3)
// Mul将z设置为乘积x * y并返回z。
BInt_ret = BInt.Mul(x, y)
fmt.Println()
fmt.Println("x:", x)
fmt.Println("y:", y)
fmt.Println("BInt_ret:", BInt_ret)
fmt.Println("BInt:", BInt)
//输出:
//x: 2
//y: 3
BInt = big.NewInt(3)
// MulRange将z设置为[a,b]范围内的所有整数的乘积,并返回z。
//如果a> b(空范围),则结果为1。
BInt_ret = BInt.Mul(x, y)
fmt.Println()
fmt.Println("x:", x)
fmt.Println("y:", y)
fmt.Println("BInt_ret:", BInt_ret)
fmt.Println("BInt:", BInt)
//BInt: 720
x = big.NewInt(23)
//x = big.NewInt(22)
//x = big.NewInt(21)
//x = big.NewInt(20)
//x = big.NewInt(17)
//x = big.NewInt(16)
//x = big.NewInt(15)
BInt_ret = BInt.MulRange(2, 6) //2*3*4*5*6
//x = big.NewInt(13)
//x = big.NewInt(12)
fmt.Println("BInt_ret:", BInt_ret)
fmt.Println("BInt:", BInt)
//y = big.NewInt(9)//莫名的出现不能停止的情况
//y = big.NewInt(8)//invalid 2nd argument to Int.Jacobi: need odd integer but got 8(译为:Int.Jacobi的无效第二个参数:需要奇数但得到8)
y = big.NewInt(7)
BInt = big.NewInt(19)
// 如果x不是平方模p,则ModSqrt保持z不变并返回nil。 如果p不是一个奇整数,则此函数会出现紧急情况。
BInt_ret = BInt.ModSqrt(x, y)
fmt.Println()
fmt.Println("x:", x)
fmt.Println("y:", y)
fmt.Println("BInt_ret:", BInt_ret)
fmt.Println("BInt:", BInt)
//23输出:
//x: 23
//y: 7
//BInt_ret: 4
//BInt: 4
//22输出:
//x: 22
//y: 7
//BInt_ret: 1
//BInt: 1
BInt_ret = BInt.ModSqrt(x, y)
//21输出:
//x: 21
fmt.Println("x:", x)
fmt.Println("y:", y)
fmt.Println("BInt_ret:", BInt_ret)
fmt.Println("BInt:", BInt)
//20输出:
//x: 20
//y: 7
//BInt_ret: <nil>
//BInt: 19
//18输出:
//x: 18
//y: 7
//BInt_ret: 2
//BInt: 2
//y=9时候出现bug
//目前还不清楚这个api的具体的用法到底是怎么样的!
//x = big.NewInt(23)
x = big.NewInt(22)
y = big.NewInt(7)
BInt = big.NewInt(11)
// ModInverse将z设置为环ℤ/nℤ中g的乘法逆,然后返回z。
// 如果g和n不是相对质数,则g在环ℤ/nℤ中没有乘法逆。 在这种情况下,z不变,返回值为nil。
//将z设为g相对p的模逆(即z、g满足(z * g) % p == 1)。返回值z大于0小于p。
BInt_ret = BInt.ModInverse(x, y)
fmt.Println()
fmt.Println("x:", x)
fmt.Println("y:", y)
fmt.Println("BInt_ret:", BInt_ret)
fmt.Println("BInt:", BInt)
//输出:
//x: 23
//y: 7
//BInt_ret: 4
BInt = big.NewInt(-11)
//通过返回x的绝对值作为低端单词切片,Bits提供对x的原始(未经检查但快速的)访问。 结果和x共享相同的基础数组。
// Bits旨在支持该程序包之外缺少的底层Int功能的实现; 否则应避免。
BInt_ret111 := BInt.Bits()
fmt.Println()
BInt_ret = BInt.ModInverse(x, y)
fmt.Println("BInt_ret:", BInt_ret111[0])
fmt.Println("BInt:", BInt)
fmt.Println("x:", x)
fmt.Println("y:", y)
fmt.Println("BInt_ret:", BInt_ret)
fmt.Println("BInt:", BInt)
//输出:
//BInt_ret: [11]
//BInt_ret: 11
//BInt: -11
//BInt_ret: [5]
//BInt: -5,底层共享同一个数组
// Bits旨在支持该程序包之外缺少的底层Int功能的实现; 否则应避免。
BInt_ret111 = BInt.Bits()
BInt_ret111 := BInt.Bits()
fmt.Println("BInt_ret:", BInt_ret111)
fmt.Println("BInt_ret:", BInt_ret111[0])
fmt.Println("BInt_ret:", BInt_ret111)
fmt.Println("BInt_ret:", BInt_ret111[0])
fmt.Println("BInt:", BInt)
fmt.Println("BInt_ret:", BInt_ret111)
BInt_ret111[0] = big.Word(5)
fmt.Println("BInt_ret:", BInt_ret111)
fmt.Println("BInt:", BInt)
//BInt_ret: 1123572578993467889
//BInt: -1123572578993467889
//BInt_ret: [5]
//BInt: -5
BInt = big.NewInt(0b0000_1110)
// 0b0000_0011
// & 0b0000_0001,其实就是返回BInt第2位的值
//Bit返回x的第i位的值。 也就是说,它返回(x >> i)&1。 位索引i必须大于等于0。
BInt_ret222 := BInt.Bit(2)
BInt_ret111 = BInt.Bits()
fmt.Println("BInt_ret:", BInt_ret222)
fmt.Println("BInt:", BInt)
fmt.Println("BInt_ret:", BInt_ret111)
fmt.Println("BInt_ret:", BInt_ret111[0])
fmt.Println("BInt:", BInt)
BInt_ret111[0] = big.Word(5)
fmt.Println("BInt_ret:", BInt_ret111)
fmt.Println("BInt:", BInt)
// BitLen返回x的绝对值的长度(以位为单位)。
// 0的位长度为0。
BInt_ret333 := BInt.BitLen()
fmt.Println()
fmt.Println("BInt_ret:", BInt_ret333)
//0b0000_0110输出:
//BInt_ret: 3
//BInt: 6
//0b0000_1110输出:
BInt_ret222 := BInt.Bit(2)
//BInt: 14
fmt.Println("BInt_ret:", BInt_ret222)
fmt.Println("BInt:", BInt)
//BInt: 70
BInt = big.NewInt(16)
BInt1 := big.NewInt(0b0100_0110)
fmt.Println()
fmt.Printf("设置位之前BInt:%b\n", BInt)
fmt.Printf("设置位之前BInt1:%b\n", BInt1)
// SetBit将z设置为x,将x的第i位设置为b(0或1)。
//如果b为1,则SetBit设置z = x | (1 << i);
//如果b为0,则SetBit设置z = x&^(1 << i)。 如果b不为0或1,则SetBit将发生恐慌。
BInt_ret333 := BInt.BitLen()
fmt.Printf("设置位之后BInt:%b\n", BInt)
fmt.Println("BInt_ret:", BInt_ret333)
fmt.Println("BInt:", BInt)
BInt = big.NewInt(16)
fmt.Println()
fmt.Println("设置位之前BInt:", BInt.Bits())
var a = big.Word(1)
var b = big.Word(2)
var ls = []big.Word{a, b}
// SetBits通过将z的值设置为abs(解释为小尾数字切片)并返回z,提供对z的原始(未经检查但快速的)访问。 结果和绝对值共享相同的基础数组。
// SetBits旨在支持该程序包外部缺少的底层Int功能的实现; 否则应避免。
BInt_ret666 := BInt.SetBits(ls)
fmt.Println("设置位之后BInt_ret666:", BInt_ret666)
//输出:
//设置位之前BInt: [16]
//设置位之后BInt: 36893488147419103233
fmt.Printf("设置位之前BInt:%b\n", BInt)
fmt.Printf("设置位之前BInt1:%b\n", BInt1)
fmt.Println()
BInt = big.NewInt(16)
fmt.Println("设置位之前BInt:", BInt)
BInt_ret555 := BInt.SetBit(BInt1, 6, 0) //这里的数字从0开始。而上面的那个BitLen是从1开始的,修改的是副本
//src_ls:=[]byte{0b0000_0000,0b0000_0011}
fmt.Printf("设置位之后BInt:%b\n", BInt)
fmt.Printf("设置位之后BInt1:%b\n", BInt1)
fmt.Printf("BInt_ret:%b\n", BInt_ret555)
fmt.Println("设置位之后BInt:", BInt)
//[]byte{0b0000_0000,0b0000_0011}输出:
//设置位之前BInt: 16
fmt.Println("设置位之前BInt:", BInt.Bits())
//设置位之后BInt_ret777: 3
var a = big.Word(1)
var b = big.Word(2)
var ls = []big.Word{a, b}
//设置位之后BInt: 259
//设置位之后BInt_ret777: 259
BInt_ret666 := BInt.SetBits(ls)
fmt.Println()
fmt.Println("设置位之后BInt:", BInt)
fmt.Println("设置位之后BInt_ret666:", BInt_ret666)
// SetInt64将z设置为x并返回z。
BInt_ret888 := BInt.SetInt64(-22)
fmt.Println("设置位之后BInt:", BInt)
fmt.Println("设置位之后BInt_ret888:", BInt_ret888)
//输出:
//设置位之前BInt: 16
fmt.Println("设置位之前BInt:", BInt)
//设置位之后BInt_ret888: -22
src_ls := []byte{0b0000_0001, 0b0000_0011}
BInt_ret777 := BInt.SetBytes(src_ls) //将字节切片转为big.Int类型
fmt.Println("设置位之前BInt:", BInt)
fmt.Println("设置位之后BInt:", BInt)
fmt.Println("设置位之后BInt_ret777:", BInt_ret777)
BInt_ret888 = BInt.SetUint64(22)
fmt.Println("设置位之后BInt:", BInt)
fmt.Println("设置位之后BInt_ret888:", BInt_ret888)
//输出:
//设置位之前BInt: 16
//设置位之后BInt: 22
//设置位之后BInt_ret888: 22
fmt.Println()
BInt = big.NewInt(16)
BInt999 := big.NewInt(17)
fmt.Println("设置位之前BInt:", BInt)
//将z设置为x并返回z。
BInt_ret888 := BInt.SetInt64(-22)
fmt.Println("设置位之后BInt:", BInt)
fmt.Println("设置位之后BInt_ret888:", BInt_ret888)
fmt.Println("设置位之后BInt_ret888:", BInt_ret888)
//输出:
//设置位之前BInt: 16
//设置位之后BInt: 17
//设置位之后BInt999: 17
fmt.Println()
BInt = big.NewInt(12)
fmt.Println("设置位之前BInt:", BInt)
// SetString将z设置为s的值,以给定的底数进行解释,并返回z和一个指示成功的布尔值。整个字符串(不仅仅是前缀)必须有效才能成功。如果SetString失败,则z的值不确定(不知道怎么理解),但返回的值为nil。
//基本参数必须为0或2到MaxBase之间的值。
BInt_ret888 = BInt.SetUint64(22)
//对于<= 36的基数,小写和大写字母被认为是相同的:
fmt.Println("设置位之后BInt:", BInt)
fmt.Println("设置位之后BInt_ret888:", BInt_ret888)
//对于以0为底的数字,下划线字符``_''可能出现在底前缀和相邻数字之间以及连续数字之间;这样的下划线不会更改数字的值。
//如果没有其他错误,则将下划线的错误放置报告为错误。如果base!= 0,则下划线将不被识别,并且与其他任何无效数字字符一样起作用。
//BInt_ret888,bl:=BInt.SetString("16",10)
//BInt_ret888,bl:=BInt.SetString("17",2)
fmt.Println("设置之后BInt:", BInt)
fmt.Println("设置之后BInt:", bl)
fmt.Println("设置之后BInt_ret888:", BInt_ret888)
fmt.Println("设置位之前BInt:", BInt)
//设置之前BInt: 12
BInt_ret888 = BInt.Set(BInt999)
//设置之后BInt: true
fmt.Println("设置位之后BInt:", BInt)
fmt.Println("设置位之后BInt999:", BInt999)
fmt.Println("设置位之后BInt_ret888:", BInt_ret888)
//设置之前BInt: 12
//设置之后BInt: 1,如果失败这个值是不确定的
//设置之后BInt: false
//设置之后BInt_ret888: <nil>
//SetString("00000011",2)输出:
//设置之前BInt: 12
//设置之后BInt: 3
fmt.Println("设置之前BInt:", BInt)
//设置之后BInt_ret888: 3
//其他进制自己尝试
fmt.Println()
BInt = big.NewInt(120)
fmt.Println("设置之前BInt:", BInt)
// Source表示在[0,1 << 63)范围内均匀分布的伪随机int64值的源。
// NewSource返回一个以给定值作为种子的新伪随机源。
//与顶层函数使用的默认Source不同,此Source对于多个goroutine并发使用是不安全的。
BInt_ret888, bl := BInt.SetString("00000011", 2) //不能带0b开头或者中间下划线
//source1 := rand.NewSource(122)
fmt.Println("设置之后BInt:", BInt)
fmt.Println("设置之后BInt:", bl)
fmt.Println("设置之后BInt_ret888:", BInt_ret888)
rd1 := rand.New(source1)
// Rand在[0,n)中将z设置为伪随机数并返回z。
//由于它使用math / rand软件包,因此不得用于对安全性敏感的工作。 使用crypto / rand.Int代替。
randBigInt := BInt.Rand(rd, BInt)
//randBigInt11 := BInt.Rand(rd, BInt)
randBigInt11 := BInt.Rand(rd1, BInt)
go func() {
source2 := rand.NewSource(120)
rd2 := rand.New(source2)
randBigInt22 := BInt.Rand(rd2, BInt)
fmt.Println("随机的BigInt22是----:", randBigInt22)
}()
fmt.Println("随机的BigInt是----:", randBigInt)
fmt.Println("随机的BigInt11是----:", randBigInt11)
//source与source1相同时候输出:
//设置之前BInt: 120
//随机的BigInt是----: 13
//随机的BigInt22是----: 7
fmt.Println("设置之前BInt:", BInt)
//设置之前BInt: 120
//随机的BigInt是----: 26
//随机的BigInt11是----: 26
//随机的BigInt22是----: 7
//不大清楚机制,不建议使用
time.Sleep(1e9)
fmt.Println()
BInt = big.NewInt(120)
fmt.Println("设置之前BInt:", BInt)
//字节返回x的绝对值作为大端字节切片。
dst_byte := BInt.Bytes()
fmt.Println("big.Int转[]byte类型之前是:", BInt)
fmt.Println("big.Int转[]byte类型后是:", dst_byte)
//输出:
//设置之前BInt: 120
//big.Int转[]byte类型之前是: 120
//big.Int转[]byte类型后是: [120]
fmt.Println("随机的BigInt22是----:", randBigInt22)
BInt = big.NewInt(12)
fmt.Println("设置之前BInt:", BInt)
fmt.Println("随机的BigInt是----:", randBigInt)
fmt.Println("随机的BigInt11是----:", randBigInt11)
fmt.Println("big.Int转string类型之前是:", BInt)
fmt.Println("big.Int转string类型后是:", dst_str)
//输出:
//设置之前BInt: 12
//big.Int转string类型之前是: 12
//big.Int转string类型后是: 12
fmt.Println()
BInt = big.NewInt(121)
//BInt = big.NewInt(1)
fmt.Println("设置之前BInt:", BInt)
// JSON封送程序仅在此处用于API向后兼容(程序会明确查找这两种方法)。 JSON仅适用于TextMarshaler。
// MarshalJSON实现json.Marshaler接口。
check_err_math_big(e)
fmt.Println("设置之前BInt:", BInt)
fmt.Println("byte_MarshalJSON:", byte_MarshalJSON)
dst_byte := BInt.Bytes()
//设置之前BInt: 0
fmt.Println("big.Int转[]byte类型之前是:", BInt)
fmt.Println("big.Int转[]byte类型后是:", dst_byte)
//NewInt(1)输出:
//设置之前BInt: 1
//BInt: 1
//byte_MarshalJSON: [49]
//BInt: 121
//byte_MarshalJSON: [49 50 49],121每个位的的unicode值
fmt.Println("设置之前BInt:", BInt)
fmt.Println()
dst_str := BInt.String()
//BInt = big.NewInt(1)
fmt.Println("big.Int转string类型之前是:", BInt)
fmt.Println("big.Int转string类型后是:", dst_str)
ls111 := []byte{49, 50, 49}
e = BInt.UnmarshalJSON(ls111)
check_err_math_big(e)
fmt.Println("BInt:", BInt)
//输出:
//设置之前BInt: 11
//BInt: 121
fmt.Println("设置之前BInt:", BInt)
BInt = big.NewInt(121)
//BInt = big.NewInt(1)
fmt.Println("设置之前BInt:", BInt)
// MarshalText实现encoding.TextMarshaler接口。关于这个接口说明如下:
// TextUnmarshaler是由对象实现的接口,可以解组自身的文本表示形式。
// UnmarshalText必须能够解码MarshalText生成的格式。
fmt.Println("BInt:", BInt)
fmt.Println("byte_MarshalJSON:", byte_MarshalJSON)
ls222, e := BInt.MarshalText()
check_err_math_big(e)
fmt.Println("BInt:", BInt)
fmt.Println("ls222:", ls222)
//输出:
//设置之前BInt: 121
//BInt: 121
//ls222: [49 50 49],似乎跟MarshalJson差不多也
fmt.Println()
BInt = big.NewInt(11)
//BInt = big.NewInt(1)
fmt.Println("设置之前BInt:", BInt)
// UnmarshalText实现encoding.TextUnmarshaler接口。
ls222 = []byte{49, 50, 49}
check_err_math_big(e)
fmt.Println("BInt:", BInt)
//输出:
fmt.Println("设置之前BInt:", BInt)
//BInt: 121
ls111 := []byte{49, 50, 49}
fmt.Println()
BInt = big.NewInt(15)
fmt.Println("BInt:", BInt)
//文本返回给定基数中x的字符串表示形式。
//底数必须介于2到62之间(含2和62)。 结果将小写字母'a'至'z'用于数字值10至35,将大写字母'A'至'Z'用于数字值36至61。
//没有前缀(例如“ 0x”)添加到字符串中。 如果x是nil指针,则返回“ <nil>”。
str10 := BInt.Text(10)
str2 := BInt.Text(2)
str16 := BInt.Text(16)
fmt.Println("设置之前BInt:", BInt)
fmt.Println("str111:", str10)
fmt.Println("str8:", str8)
fmt.Println("str2:", str2)
fmt.Println("str16:", str16)
//输出:
ls222, e := BInt.MarshalText()
//BInt: 15
fmt.Println("BInt:", BInt)
fmt.Println("ls222:", ls222)
//str2: 1111
//str16: f
fmt.Println()
BInt = big.NewInt(15)
// ^ 0b1111_0110
fmt.Println("BInt之前:", BInt)
fmt.Println("BInt_arg之前:", BInt_arg)
fmt.Println("设置之前BInt:", BInt)
Int_ret := BInt.Not(BInt_arg)
ls222 = []byte{49, 50, 49}
fmt.Println("BInt之后:", BInt)
fmt.Println("BInt_arg之后:", BInt_arg)
fmt.Println("BInt:", BInt)
//输出:
//BInt之前: 15
//BInt_arg之前: 9
//BInt之后: -10
//返回值Int_ret: -10
fmt.Println("设置之前BInt:", BInt)
BInt = big.NewInt(15)
BInt_arg = big.NewInt(123)
fmt.Println("BInt之前:", BInt)
fmt.Println("BInt_arg之前:", BInt_arg)
// Neg将z设置为-x并返回z。
Int_ret = BInt.Neg(BInt_arg)
fmt.Println("BInt:", BInt)
fmt.Println("str111:", str10)
fmt.Println("str8:", str8)
fmt.Println("str2:", str2)
fmt.Println("str16:", str16)
//BInt_arg之前: 123
//BInt之后: -123
//BInt_arg之后: 123
//返回值Int_ret: -123
fmt.Println()
BInt = big.NewInt(15)
//如果x不能用uint64表示,则结果不确定。
uint64_exmp := BInt.Uint64()
fmt.Printf("BInt之后的类型是:%T,值是:%v\n", BInt, BInt)
fmt.Println("BInt之前:", BInt)
fmt.Println("BInt_arg之前:", BInt_arg)
//BInt之前: 15
Int_ret := BInt.Not(BInt_arg)
//返回值uint64_exmp的类型是:uint64,值是:15
fmt.Println("BInt之后:", BInt)
fmt.Println("BInt_arg之后:", BInt_arg)
fmt.Println("返回值Int_ret:", Int_ret)
fmt.Println("BInt之前:", BInt)
// Uint64返回x的uint64表示形式。
//如果x不能用uint64表示,则结果不确定。
int64_exmp := BInt.Int64()
fmt.Printf("BInt之后的类型是:%T,值是:%v\n", BInt, BInt)
//输出:
//BInt之前: 15
BInt_arg = big.NewInt(123)
//返回值int64_exmp的类型是:int64,值是:15
fmt.Println("BInt之前:", BInt)
fmt.Println("BInt_arg之前:", BInt_arg)
BInt = big.NewInt(15)
Int_ret = BInt.Neg(BInt_arg)
fmt.Println("BInt之后:", BInt)
fmt.Println("BInt_arg之后:", BInt_arg)
fmt.Println("返回值Int_ret:", Int_ret)
uint64_bool := BInt.IsUint64()
int64_bool1 := BInt1.IsInt64()
uint64_bool1 := BInt1.IsUint64()
fmt.Printf("BInt之后的类型是:%T,值是:%v\n", BInt, BInt)
fmt.Printf("返回值int64_bool的类型是:%T,值是:%v\n", int64_bool, int64_bool)
fmt.Printf("返回值uint64_bool1的类型是:%T,值是:%v\n", uint64_bool1, uint64_bool1)
//输出:
//BInt之前: 15
fmt.Println("BInt之前:", BInt)
//返回值int64_bool的类型是:bool,值是:true
//返回值uint64_bool的类型是:bool,值是:true
uint64_exmp := BInt.Uint64()
//返回值uint64_bool1的类型是:bool,值是:false
fmt.Printf("BInt之后的类型是:%T,值是:%v\n", BInt, BInt)
fmt.Printf("返回值uint64_exmp的类型是:%T,值是:%v\n", uint64_exmp, uint64_exmp)
BInt = big.NewInt(15)
fmt.Println("BInt之前:", BInt)
//将由x.Text(base)生成的x的字符串表示形式追加到buf,并返回扩展的缓冲区。
buf := make([]byte, 3)
buf = BInt.Append(buf, 10)
fmt.Println("BInt之后:", BInt)
fmt.Println("BInt之前:", BInt)
//fmt.Println("追加到字节切片后的切片为:",ls333)
//输出:
int64_exmp := BInt.Int64()
//追加之前的字节切片buf: [0 0 0]
fmt.Printf("BInt之后的类型是:%T,值是:%v\n", BInt, BInt)
fmt.Printf("返回值int64_exmp的类型是:%T,值是:%v\n", int64_exmp, int64_exmp)
//追加到字节切片后的切片为: [0 0 0 49 53],说明不是原地追加的,当然也可以原地追加,看接受者
fmt.Println()
BInt = big.NewInt(15)
BInt1 = big.NewInt(13)
fmt.Println("BInt之前:", BInt)
//二项式将z设置为(n,k)的二项式系数,并返回z。
//具体请看:https://baike.baidu.com/pic/%E4%BA%8C%E9%A1%B9%E5%BC%8F%E7%B3%BB%E6%95%B0/6763242/0/377adab44aed2e73b9e960568c01a18b87d6fa4c?fr=lemma&ct=single#aid=0&pic=377adab44aed2e73b9e960568c01a18b87d6fa4c
BInt1 = BInt.Binomial(4, 2)
fmt.Println("BInt之前:", BInt)
fmt.Println("BInt之后:", BInt)
int64_bool := BInt.IsInt64()
uint64_bool := BInt.IsUint64()
//BInt之前: 15
int64_bool1 := BInt1.IsInt64()
uint64_bool1 := BInt1.IsUint64()
fmt.Printf("BInt之后的类型是:%T,值是:%v\n", BInt, BInt)
fmt.Printf("返回值int64_bool的类型是:%T,值是:%v\n", int64_bool, int64_bool)
fmt.Printf("返回值uint64_bool的类型是:%T,值是:%v\n", uint64_bool, uint64_bool)
fmt.Printf("返回值int64_bool1的类型是:%T,值是:%v\n", int64_bool1, int64_bool1)
fmt.Printf("返回值uint64_bool1的类型是:%T,值是:%v\n", uint64_bool1, uint64_bool1)
fmt.Println("BInt之前:", BInt)
// GCD将z设置为a和b的最大公约数(都必须大于0),并返回z。
//如果x或y不为nil,则GCD会将其值设置为z = a * x + b * y。
//如果a或b均<= 0,则GCD设置z = x = y = 0。
BInt2 := BInt_r.GCD(nil, nil, BInt, BInt1)
fmt.Println("BInt之后:", BInt)
fmt.Println("BInt1之后:", BInt1)
//输出:
//BInt之前: 12
//BInt之后: 12
fmt.Println("BInt之前:", BInt)
//BInt2之后: 4
buf := make([]byte, 3)
fmt.Println("追加之前的字节切片buf:", buf)
fmt.Println()
buf = BInt.Append(buf, 10)
BInt1 = big.NewInt(8)
fmt.Println("BInt之后:", BInt)
fmt.Println("追加之后的字节切片buf:", buf)
fmt.Println("BInt之前:", BInt)
// GCD将z设置为a和b的最大公约数(都必须大于0),并返回z。
//如果x或y不为nil,则GCD会将其值设置为z = a * x + b * y。
//如果a或b均<= 0,则GCD设置z = x = y = 0。
BInt2 = BInt_r.GCD(big.NewInt(-2), big.NewInt(-4), BInt, BInt1)
fmt.Println("BInt之后:", BInt)
fmt.Println("BInt1之后:", BInt1)
//输出:
//BInt之前: 12
//BInt之后: 12
//BInt1之后: 8
fmt.Println("BInt之前:", BInt)
//BInt_r之后: 4,似乎x和y并不起作用
BInt1 = BInt.Binomial(4, 2)
BInt = big.NewInt(12)
fmt.Println("BInt之后:", BInt)
fmt.Println("BInt1之后:", BInt1)
//或设置z = x | y并返回z。
BInt2 = BInt.Or(big.NewInt(0b0000_0001), big.NewInt(0b0000_0011))
fmt.Println("BInt之后:", BInt)
fmt.Println("BInt2之后:", BInt2)
//BInt之前: 12
//BInt之后: 3
//BInt2之后: 3
fmt.Println()
fmt.Println("BInt之前:", BInt)
fmt.Println("BInt之前:", BInt)
// Quo将z设为y!= 0时候x / y的商并返回z。
BInt2 := BInt_r.GCD(nil, nil, BInt, BInt1)
// Quo实现了截断的除法(例如Go); 有关更多详细信息,请参见QuoRem。
fmt.Println("BInt之后:", BInt)
fmt.Println("BInt1之后:", BInt1)
fmt.Println("BInt2之后:", BInt2)
fmt.Println("BInt_r之后:", BInt_r)
fmt.Println("BInt2之后:", BInt2)
//2输出:
//BInt之前: 12
//BInt之后: 4
//BInt2之后: 4
//3输出:
//BInt之后: 2
//BInt2之后: 2
fmt.Println()
BInt = big.NewInt(12)
fmt.Println("BInt之前:", BInt)
fmt.Println("BInt之前:", BInt)
// QuoRem将z设置为x / y的商,将r设置为x%y的余数,并返回y!= 0的(z,r)对。
BInt2 = BInt_r.GCD(big.NewInt(-2), big.NewInt(-4), BInt, BInt1)
// QuoRem实现T划分和模数(如Go):
fmt.Println("BInt之后:", BInt)
fmt.Println("BInt1之后:", BInt1)
fmt.Println("BInt2之后:", BInt2)
fmt.Println("BInt_r之后:", BInt_r)
BInt_re1, BInt_re2 := BInt.QuoRem(big.NewInt(17), big.NewInt(5), BInt1)
fmt.Println("BInt之后:", BInt)
fmt.Println("BInt1之后:", BInt1)
fmt.Println("BInt_re1之后:", BInt_re1)
fmt.Println("BInt_re2之后:", BInt_re2)
//输出:
//BInt1之后: 2
//BInt_re1之后: 3
//BInt_re2之后: 2
fmt.Println("BInt之前:", BInt)
fmt.Println()
BInt2 = BInt.Or(big.NewInt(0b0000_0001), big.NewInt(0b0000_0011))
fmt.Println("BInt之后:", BInt)