zoukankan      html  css  js  c++  java
  • 无符号256位整数运算(转)

    无符号256位整数运算

    源代码出处:github blue-app-eth/src_common

    这个源代码包括两个文件,分别是uint256.h和uint256.c。

    有关计算是基于类型uint128_t上实现的。

    uint256.h代码如下:

    1.  
      /*******************************************************************************
    2.  
      * Ledger Blue
    3.  
      * (c) 2016 Ledger
    4.  
      *
    5.  
      * Licensed under the Apache License, Version 2.0 (the "License");
    6.  
      * you may not use this file except in compliance with the License.
    7.  
      * You may obtain a copy of the License at
    8.  
      *
    9.  
      * http://www.apache.org/licenses/LICENSE-2.0
    10.  
      *
    11.  
      * Unless required by applicable law or agreed to in writing, software
    12.  
      * distributed under the License is distributed on an "AS IS" BASIS,
    13.  
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14.  
      * See the License for the specific language governing permissions and
    15.  
      * limitations under the License.
    16.  
      ********************************************************************************/
    17.  
       
    18.  
      // Adapted from https://github.com/calccrypto/uint256_t
    19.  
       
    20.  
      #include <stdint.h>
    21.  
      #include <stdbool.h>
    22.  
       
    23.  
      typedef struct uint128_t { uint64_t elements[2]; } uint128_t;
    24.  
       
    25.  
      typedef struct uint256_t { uint128_t elements[2]; } uint256_t;
    26.  
       
    27.  
      #define UPPER_P(x) x->elements[0]
    28.  
      #define LOWER_P(x) x->elements[1]
    29.  
      #define UPPER(x) x.elements[0]
    30.  
      #define LOWER(x) x.elements[1]
    31.  
       
    32.  
      void readu128BE(uint8_t *buffer, uint128_t *target);
    33.  
      void readu256BE(uint8_t *buffer, uint256_t *target);
    34.  
      bool zero128(uint128_t *number);
    35.  
      bool zero256(uint256_t *number);
    36.  
      void copy128(uint128_t *target, uint128_t *number);
    37.  
      void copy256(uint256_t *target, uint256_t *number);
    38.  
      void clear128(uint128_t *target);
    39.  
      void clear256(uint256_t *target);
    40.  
      void shiftl128(uint128_t *number, uint32_t value, uint128_t *target);
    41.  
      void shiftr128(uint128_t *number, uint32_t value, uint128_t *target);
    42.  
      void shiftl256(uint256_t *number, uint32_t value, uint256_t *target);
    43.  
      void shiftr256(uint256_t *number, uint32_t value, uint256_t *target);
    44.  
      uint32_t bits128(uint128_t *number);
    45.  
      uint32_t bits256(uint256_t *number);
    46.  
      bool equal128(uint128_t *number1, uint128_t *number2);
    47.  
      bool equal256(uint256_t *number1, uint256_t *number2);
    48.  
      bool gt128(uint128_t *number1, uint128_t *number2);
    49.  
      bool gt256(uint256_t *number1, uint256_t *number2);
    50.  
      bool gte128(uint128_t *number1, uint128_t *number2);
    51.  
      bool gte256(uint256_t *number1, uint256_t *number2);
    52.  
      void add128(uint128_t *number1, uint128_t *number2, uint128_t *target);
    53.  
      void add256(uint256_t *number1, uint256_t *number2, uint256_t *target);
    54.  
      void minus128(uint128_t *number1, uint128_t *number2, uint128_t *target);
    55.  
      void minus256(uint256_t *number1, uint256_t *number2, uint256_t *target);
    56.  
      void or128(uint128_t *number1, uint128_t *number2, uint128_t *target);
    57.  
      void or256(uint256_t *number1, uint256_t *number2, uint256_t *target);
    58.  
      void mul128(uint128_t *number1, uint128_t *number2, uint128_t *target);
    59.  
      void mul256(uint256_t *number1, uint256_t *number2, uint256_t *target);
    60.  
      void divmod128(uint128_t *l, uint128_t *r, uint128_t *div, uint128_t *mod);
    61.  
      void divmod256(uint256_t *l, uint256_t *r, uint256_t *div, uint256_t *mod);
    62.  
      bool tostring128(uint128_t *number, uint32_t base, char *out,
    63.  
      uint32_t outLength);
    64.  
      bool tostring256(uint256_t *number, uint32_t base, char *out,
    65.  
      uint32_t outLength);

    uint256.c代码如下:
    1.  
      /*******************************************************************************
    2.  
      * Ledger Blue
    3.  
      * (c) 2016 Ledger
    4.  
      *
    5.  
      * Licensed under the Apache License, Version 2.0 (the "License");
    6.  
      * you may not use this file except in compliance with the License.
    7.  
      * You may obtain a copy of the License at
    8.  
      *
    9.  
      * http://www.apache.org/licenses/LICENSE-2.0
    10.  
      *
    11.  
      * Unless required by applicable law or agreed to in writing, software
    12.  
      * distributed under the License is distributed on an "AS IS" BASIS,
    13.  
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14.  
      * See the License for the specific language governing permissions and
    15.  
      * limitations under the License.
    16.  
      ********************************************************************************/
    17.  
       
    18.  
      // Adapted from https://github.com/calccrypto/uint256_t
    19.  
       
    20.  
      #include <stdio.h>
    21.  
      #include <stdlib.h>
    22.  
      #include "uint256.h"
    23.  
       
    24.  
      static const char HEXDIGITS[] = "0123456789abcdef";
    25.  
       
    26.  
      static uint64_t readUint64BE(uint8_t *buffer) {
    27.  
      return (((uint64_t)buffer[0]) << 56) | (((uint64_t)buffer[1]) << 48) |
    28.  
      (((uint64_t)buffer[2]) << 40) | (((uint64_t)buffer[3]) << 32) |
    29.  
      (((uint64_t)buffer[4]) << 24) | (((uint64_t)buffer[5]) << 16) |
    30.  
      (((uint64_t)buffer[6]) << 8) | (((uint64_t)buffer[7]));
    31.  
      }
    32.  
       
    33.  
      void readu128BE(uint8_t *buffer, uint128_t *target) {
    34.  
      UPPER_P(target) = readUint64BE(buffer);
    35.  
      LOWER_P(target) = readUint64BE(buffer + 8);
    36.  
      }
    37.  
       
    38.  
      void readu256BE(uint8_t *buffer, uint256_t *target) {
    39.  
      readu128BE(buffer, &UPPER_P(target));
    40.  
      readu128BE(buffer + 16, &LOWER_P(target));
    41.  
      }
    42.  
       
    43.  
      bool zero128(uint128_t *number) {
    44.  
      return ((LOWER_P(number) == 0) && (UPPER_P(number) == 0));
    45.  
      }
    46.  
       
    47.  
      bool zero256(uint256_t *number) {
    48.  
      return (zero128(&LOWER_P(number)) && zero128(&UPPER_P(number)));
    49.  
      }
    50.  
       
    51.  
      void copy128(uint128_t *target, uint128_t *number) {
    52.  
      UPPER_P(target) = UPPER_P(number);
    53.  
      LOWER_P(target) = LOWER_P(number);
    54.  
      }
    55.  
       
    56.  
      void copy256(uint256_t *target, uint256_t *number) {
    57.  
      copy128(&UPPER_P(target), &UPPER_P(number));
    58.  
      copy128(&LOWER_P(target), &LOWER_P(number));
    59.  
      }
    60.  
       
    61.  
      void clear128(uint128_t *target) {
    62.  
      UPPER_P(target) = 0;
    63.  
      LOWER_P(target) = 0;
    64.  
      }
    65.  
       
    66.  
      void clear256(uint256_t *target) {
    67.  
      clear128(&UPPER_P(target));
    68.  
      clear128(&LOWER_P(target));
    69.  
      }
    70.  
       
    71.  
      void shiftl128(uint128_t *number, uint32_t value, uint128_t *target) {
    72.  
      if (value >= 128) {
    73.  
      clear128(target);
    74.  
      } else if (value == 64) {
    75.  
      UPPER_P(target) = LOWER_P(number);
    76.  
      LOWER_P(target) = 0;
    77.  
      } else if (value == 0) {
    78.  
      copy128(target, number);
    79.  
      } else if (value < 64) {
    80.  
      UPPER_P(target) =
    81.  
      (UPPER_P(number) << value) + (LOWER_P(number) >> (64 - value));
    82.  
      LOWER_P(target) = (LOWER_P(number) << value);
    83.  
      } else if ((128 > value) && (value > 64)) {
    84.  
      UPPER_P(target) = LOWER_P(number) << (value - 64);
    85.  
      LOWER_P(target) = 0;
    86.  
      } else {
    87.  
      clear128(target);
    88.  
      }
    89.  
      }
    90.  
       
    91.  
      void shiftl256(uint256_t *number, uint32_t value, uint256_t *target) {
    92.  
      if (value >= 256) {
    93.  
      clear256(target);
    94.  
      } else if (value == 128) {
    95.  
      copy128(&UPPER_P(target), &LOWER_P(number));
    96.  
      clear128(&LOWER_P(target));
    97.  
      } else if (value == 0) {
    98.  
      copy256(target, number);
    99.  
      } else if (value < 128) {
    100.  
      uint128_t tmp1;
    101.  
      uint128_t tmp2;
    102.  
      uint256_t result;
    103.  
      shiftl128(&UPPER_P(number), value, &tmp1);
    104.  
      shiftr128(&LOWER_P(number), (128 - value), &tmp2);
    105.  
      add128(&tmp1, &tmp2, &UPPER(result));
    106.  
      shiftl128(&LOWER_P(number), value, &LOWER(result));
    107.  
      copy256(target, &result);
    108.  
      } else if ((256 > value) && (value > 128)) {
    109.  
      shiftl128(&LOWER_P(number), (value - 128), &UPPER_P(target));
    110.  
      clear128(&LOWER_P(target));
    111.  
      } else {
    112.  
      clear256(target);
    113.  
      }
    114.  
      }
    115.  
       
    116.  
      void shiftr128(uint128_t *number, uint32_t value, uint128_t *target) {
    117.  
      if (value >= 128) {
    118.  
      clear128(target);
    119.  
      } else if (value == 64) {
    120.  
      UPPER_P(target) = 0;
    121.  
      LOWER_P(target) = UPPER_P(number);
    122.  
      } else if (value == 0) {
    123.  
      copy128(target, number);
    124.  
      } else if (value < 64) {
    125.  
      uint128_t result;
    126.  
      UPPER(result) = UPPER_P(number) >> value;
    127.  
      LOWER(result) =
    128.  
      (UPPER_P(number) << (64 - value)) + (LOWER_P(number) >> value);
    129.  
      copy128(target, &result);
    130.  
      } else if ((128 > value) && (value > 64)) {
    131.  
      LOWER_P(target) = UPPER_P(number) >> (value - 64);
    132.  
      UPPER_P(target) = 0;
    133.  
      } else {
    134.  
      clear128(target);
    135.  
      }
    136.  
      }
    137.  
       
    138.  
      void shiftr256(uint256_t *number, uint32_t value, uint256_t *target) {
    139.  
      if (value >= 256) {
    140.  
      clear256(target);
    141.  
      } else if (value == 128) {
    142.  
      copy128(&LOWER_P(target), &UPPER_P(number));
    143.  
      clear128(&UPPER_P(target));
    144.  
      } else if (value == 0) {
    145.  
      copy256(target, number);
    146.  
      } else if (value < 128) {
    147.  
      uint128_t tmp1;
    148.  
      uint128_t tmp2;
    149.  
      uint256_t result;
    150.  
      shiftr128(&UPPER_P(number), value, &UPPER(result));
    151.  
      shiftr128(&LOWER_P(number), value, &tmp1);
    152.  
      shiftl128(&UPPER_P(number), (128 - value), &tmp2);
    153.  
      add128(&tmp1, &tmp2, &LOWER(result));
    154.  
      copy256(target, &result);
    155.  
      } else if ((256 > value) && (value > 128)) {
    156.  
      shiftr128(&UPPER_P(number), (value - 128), &LOWER_P(target));
    157.  
      clear128(&UPPER_P(target));
    158.  
      } else {
    159.  
      clear256(target);
    160.  
      }
    161.  
      }
    162.  
       
    163.  
      uint32_t bits128(uint128_t *number) {
    164.  
      uint32_t result = 0;
    165.  
      if (UPPER_P(number)) {
    166.  
      result = 64;
    167.  
      uint64_t up = UPPER_P(number);
    168.  
      while (up) {
    169.  
      up >>= 1;
    170.  
      result++;
    171.  
      }
    172.  
      } else {
    173.  
      uint64_t low = LOWER_P(number);
    174.  
      while (low) {
    175.  
      low >>= 1;
    176.  
      result++;
    177.  
      }
    178.  
      }
    179.  
      return result;
    180.  
      }
    181.  
       
    182.  
      uint32_t bits256(uint256_t *number) {
    183.  
      uint32_t result = 0;
    184.  
      if (!zero128(&UPPER_P(number))) {
    185.  
      result = 128;
    186.  
      uint128_t up;
    187.  
      copy128(&up, &UPPER_P(number));
    188.  
      while (!zero128(&up)) {
    189.  
      shiftr128(&up, 1, &up);
    190.  
      result++;
    191.  
      }
    192.  
      } else {
    193.  
      uint128_t low;
    194.  
      copy128(&low, &LOWER_P(number));
    195.  
      while (!zero128(&low)) {
    196.  
      shiftr128(&low, 1, &low);
    197.  
      result++;
    198.  
      }
    199.  
      }
    200.  
      return result;
    201.  
      }
    202.  
       
    203.  
      bool equal128(uint128_t *number1, uint128_t *number2) {
    204.  
      return (UPPER_P(number1) == UPPER_P(number2)) &&
    205.  
      (LOWER_P(number1) == LOWER_P(number2));
    206.  
      }
    207.  
       
    208.  
      bool equal256(uint256_t *number1, uint256_t *number2) {
    209.  
      return (equal128(&UPPER_P(number1), &UPPER_P(number2)) &&
    210.  
      equal128(&LOWER_P(number1), &LOWER_P(number2)));
    211.  
      }
    212.  
       
    213.  
      bool gt128(uint128_t *number1, uint128_t *number2) {
    214.  
      if (UPPER_P(number1) == UPPER_P(number2)) {
    215.  
      return (LOWER_P(number1) > LOWER_P(number2));
    216.  
      }
    217.  
      return (UPPER_P(number1) > UPPER_P(number2));
    218.  
      }
    219.  
       
    220.  
      bool gt256(uint256_t *number1, uint256_t *number2) {
    221.  
      if (equal128(&UPPER_P(number1), &UPPER_P(number2))) {
    222.  
      return gt128(&LOWER_P(number1), &LOWER_P(number2));
    223.  
      }
    224.  
      return gt128(&UPPER_P(number1), &UPPER_P(number2));
    225.  
      }
    226.  
       
    227.  
      bool gte128(uint128_t *number1, uint128_t *number2) {
    228.  
      return gt128(number1, number2) || equal128(number1, number2);
    229.  
      }
    230.  
       
    231.  
      bool gte256(uint256_t *number1, uint256_t *number2) {
    232.  
      return gt256(number1, number2) || equal256(number1, number2);
    233.  
      }
    234.  
       
    235.  
      void add128(uint128_t *number1, uint128_t *number2, uint128_t *target) {
    236.  
      UPPER_P(target) =
    237.  
      UPPER_P(number1) + UPPER_P(number2) +
    238.  
      ((LOWER_P(number1) + LOWER_P(number2)) < LOWER_P(number1));
    239.  
      LOWER_P(target) = LOWER_P(number1) + LOWER_P(number2);
    240.  
      }
    241.  
       
    242.  
      void add256(uint256_t *number1, uint256_t *number2, uint256_t *target) {
    243.  
      uint128_t tmp;
    244.  
      add128(&UPPER_P(number1), &UPPER_P(number2), &UPPER_P(target));
    245.  
      add128(&LOWER_P(number1), &LOWER_P(number2), &tmp);
    246.  
      if (gt128(&LOWER_P(number1), &tmp)) {
    247.  
      uint128_t one;
    248.  
      UPPER(one) = 0;
    249.  
      LOWER(one) = 1;
    250.  
      add128(&UPPER_P(target), &one, &UPPER_P(target));
    251.  
      }
    252.  
      add128(&LOWER_P(number1), &LOWER_P(number2), &LOWER_P(target));
    253.  
      }
    254.  
       
    255.  
      void minus128(uint128_t *number1, uint128_t *number2, uint128_t *target) {
    256.  
      UPPER_P(target) =
    257.  
      UPPER_P(number1) - UPPER_P(number2) -
    258.  
      ((LOWER_P(number1) - LOWER_P(number2)) > LOWER_P(number1));
    259.  
      LOWER_P(target) = LOWER_P(number1) - LOWER_P(number2);
    260.  
      }
    261.  
       
    262.  
      void minus256(uint256_t *number1, uint256_t *number2, uint256_t *target) {
    263.  
      uint128_t tmp;
    264.  
      minus128(&UPPER_P(number1), &UPPER_P(number2), &UPPER_P(target));
    265.  
      minus128(&LOWER_P(number1), &LOWER_P(number2), &tmp);
    266.  
      if (gt128(&tmp, &LOWER_P(number1))) {
    267.  
      uint128_t one;
    268.  
      UPPER(one) = 0;
    269.  
      LOWER(one) = 1;
    270.  
      minus128(&UPPER_P(target), &one, &UPPER_P(target));
    271.  
      }
    272.  
      minus128(&LOWER_P(number1), &LOWER_P(number2), &LOWER_P(target));
    273.  
      }
    274.  
       
    275.  
      void or128(uint128_t *number1, uint128_t *number2, uint128_t *target) {
    276.  
      UPPER_P(target) = UPPER_P(number1) | UPPER_P(number2);
    277.  
      LOWER_P(target) = LOWER_P(number1) | LOWER_P(number2);
    278.  
      }
    279.  
       
    280.  
      void or256(uint256_t *number1, uint256_t *number2, uint256_t *target) {
    281.  
      or128(&UPPER_P(number1), &UPPER_P(number2), &UPPER_P(target));
    282.  
      or128(&LOWER_P(number1), &LOWER_P(number2), &LOWER_P(target));
    283.  
      }
    284.  
       
    285.  
      void mul128(uint128_t *number1, uint128_t *number2, uint128_t *target) {
    286.  
      uint64_t top[4] = {UPPER_P(number1) >> 32, UPPER_P(number1) & 0xffffffff,
    287.  
      LOWER_P(number1) >> 32, LOWER_P(number1) & 0xffffffff};
    288.  
      uint64_t bottom[4] = {UPPER_P(number2) >> 32, UPPER_P(number2) & 0xffffffff,
    289.  
      LOWER_P(number2) >> 32,
    290.  
      LOWER_P(number2) & 0xffffffff};
    291.  
      uint64_t products[4][4];
    292.  
      uint128_t tmp, tmp2;
    293.  
       
    294.  
      for (int y = 3; y > -1; y--) {
    295.  
      for (int x = 3; x > -1; x--) {
    296.  
      products[3 - x][y] = top[x] * bottom[y];
    297.  
      }
    298.  
      }
    299.  
       
    300.  
      uint64_t fourth32 = products[0][3] & 0xffffffff;
    301.  
      uint64_t third32 = (products[0][2] & 0xffffffff) + (products[0][3] >> 32);
    302.  
      uint64_t second32 = (products[0][1] & 0xffffffff) + (products[0][2] >> 32);
    303.  
      uint64_t first32 = (products[0][0] & 0xffffffff) + (products[0][1] >> 32);
    304.  
       
    305.  
      third32 += products[1][3] & 0xffffffff;
    306.  
      second32 += (products[1][2] & 0xffffffff) + (products[1][3] >> 32);
    307.  
      first32 += (products[1][1] & 0xffffffff) + (products[1][2] >> 32);
    308.  
       
    309.  
      second32 += products[2][3] & 0xffffffff;
    310.  
      first32 += (products[2][2] & 0xffffffff) + (products[2][3] >> 32);
    311.  
       
    312.  
      first32 += products[3][3] & 0xffffffff;
    313.  
       
    314.  
      UPPER(tmp) = first32 << 32;
    315.  
      LOWER(tmp) = 0;
    316.  
      UPPER(tmp2) = third32 >> 32;
    317.  
      LOWER(tmp2) = third32 << 32;
    318.  
      add128(&tmp, &tmp2, target);
    319.  
      UPPER(tmp) = second32;
    320.  
      LOWER(tmp) = 0;
    321.  
      add128(&tmp, target, &tmp2);
    322.  
      UPPER(tmp) = 0;
    323.  
      LOWER(tmp) = fourth32;
    324.  
      add128(&tmp, &tmp2, target);
    325.  
      }
    326.  
       
    327.  
      void mul256(uint256_t *number1, uint256_t *number2, uint256_t *target) {
    328.  
      uint128_t top[4];
    329.  
      uint128_t bottom[4];
    330.  
      uint128_t products[4][4];
    331.  
      uint128_t tmp, tmp2, fourth64, third64, second64, first64;
    332.  
      uint256_t target1, target2;
    333.  
      UPPER(top[0]) = 0;
    334.  
      LOWER(top[0]) = UPPER(UPPER_P(number1));
    335.  
      UPPER(top[1]) = 0;
    336.  
      LOWER(top[1]) = LOWER(UPPER_P(number1));
    337.  
      UPPER(top[2]) = 0;
    338.  
      LOWER(top[2]) = UPPER(LOWER_P(number1));
    339.  
      UPPER(top[3]) = 0;
    340.  
      LOWER(top[3]) = LOWER(LOWER_P(number1));
    341.  
      UPPER(bottom[0]) = 0;
    342.  
      LOWER(bottom[0]) = UPPER(UPPER_P(number2));
    343.  
      UPPER(bottom[1]) = 0;
    344.  
      LOWER(bottom[1]) = LOWER(UPPER_P(number2));
    345.  
      UPPER(bottom[2]) = 0;
    346.  
      LOWER(bottom[2]) = UPPER(LOWER_P(number2));
    347.  
      UPPER(bottom[3]) = 0;
    348.  
      LOWER(bottom[3]) = LOWER(LOWER_P(number2));
    349.  
       
    350.  
      for (int y = 3; y > -1; y--) {
    351.  
      for (int x = 3; x > -1; x--) {
    352.  
      mul128(&top[x], &bottom[y], &products[3 - x][y]);
    353.  
      }
    354.  
      }
    355.  
       
    356.  
      UPPER(fourth64) = 0;
    357.  
      LOWER(fourth64) = LOWER(products[0][3]);
    358.  
      UPPER(tmp) = 0;
    359.  
      LOWER(tmp) = LOWER(products[0][2]);
    360.  
      UPPER(tmp2) = 0;
    361.  
      LOWER(tmp2) = UPPER(products[0][3]);
    362.  
      add128(&tmp, &tmp2, &third64);
    363.  
      UPPER(tmp) = 0;
    364.  
      LOWER(tmp) = LOWER(products[0][1]);
    365.  
      UPPER(tmp2) = 0;
    366.  
      LOWER(tmp2) = UPPER(products[0][2]);
    367.  
      add128(&tmp, &tmp2, &second64);
    368.  
      UPPER(tmp) = 0;
    369.  
      LOWER(tmp) = LOWER(products[0][0]);
    370.  
      UPPER(tmp2) = 0;
    371.  
      LOWER(tmp2) = UPPER(products[0][1]);
    372.  
      add128(&tmp, &tmp2, &first64);
    373.  
       
    374.  
      UPPER(tmp) = 0;
    375.  
      LOWER(tmp) = LOWER(products[1][3]);
    376.  
      add128(&tmp, &third64, &tmp2);
    377.  
      copy128(&third64, &tmp2);
    378.  
      UPPER(tmp) = 0;
    379.  
      LOWER(tmp) = LOWER(products[1][2]);
    380.  
      add128(&tmp, &second64, &tmp2);
    381.  
      UPPER(tmp) = 0;
    382.  
      LOWER(tmp) = UPPER(products[1][3]);
    383.  
      add128(&tmp, &tmp2, &second64);
    384.  
      UPPER(tmp) = 0;
    385.  
      LOWER(tmp) = LOWER(products[1][1]);
    386.  
      add128(&tmp, &first64, &tmp2);
    387.  
      UPPER(tmp) = 0;
    388.  
      LOWER(tmp) = UPPER(products[1][2]);
    389.  
      add128(&tmp, &tmp2, &first64);
    390.  
       
    391.  
      UPPER(tmp) = 0;
    392.  
      LOWER(tmp) = LOWER(products[2][3]);
    393.  
      add128(&tmp, &second64, &tmp2);
    394.  
      copy128(&second64, &tmp2);
    395.  
      UPPER(tmp) = 0;
    396.  
      LOWER(tmp) = LOWER(products[2][2]);
    397.  
      add128(&tmp, &first64, &tmp2);
    398.  
      UPPER(tmp) = 0;
    399.  
      LOWER(tmp) = UPPER(products[2][3]);
    400.  
      add128(&tmp, &tmp2, &first64);
    401.  
       
    402.  
      UPPER(tmp) = 0;
    403.  
      LOWER(tmp) = LOWER(products[3][3]);
    404.  
      add128(&tmp, &first64, &tmp2);
    405.  
      copy128(&first64, &tmp2);
    406.  
       
    407.  
      clear256(&target1);
    408.  
      shiftl128(&first64, 64, &UPPER(target1));
    409.  
      clear256(&target2);
    410.  
      UPPER(UPPER(target2)) = UPPER(third64);
    411.  
      shiftl128(&third64, 64, &LOWER(target2));
    412.  
      add256(&target1, &target2, target);
    413.  
      clear256(&target1);
    414.  
      copy128(&UPPER(target1), &second64);
    415.  
      add256(&target1, target, &target2);
    416.  
      clear256(&target1);
    417.  
      copy128(&LOWER(target1), &fourth64);
    418.  
      add256(&target1, &target2, target);
    419.  
      }
    420.  
       
    421.  
      void divmod128(uint128_t *l, uint128_t *r, uint128_t *retDiv,
    422.  
      uint128_t *retMod) {
    423.  
      uint128_t copyd, adder, resDiv, resMod;
    424.  
      uint128_t one;
    425.  
      UPPER(one) = 0;
    426.  
      LOWER(one) = 1;
    427.  
      uint32_t diffBits = bits128(l) - bits128(r);
    428.  
      clear128(&resDiv);
    429.  
      copy128(&resMod, l);
    430.  
      if (gt128(r, l)) {
    431.  
      copy128(retMod, l);
    432.  
      clear128(retDiv);
    433.  
      } else {
    434.  
      shiftl128(r, diffBits, &copyd);
    435.  
      shiftl128(&one, diffBits, &adder);
    436.  
      if (gt128(&copyd, &resMod)) {
    437.  
      shiftr128(&copyd, 1, &copyd);
    438.  
      shiftr128(&adder, 1, &adder);
    439.  
      }
    440.  
      while (gte128(&resMod, r)) {
    441.  
      if (gte128(&resMod, &copyd)) {
    442.  
      minus128(&resMod, &copyd, &resMod);
    443.  
      or128(&resDiv, &adder, &resDiv);
    444.  
      }
    445.  
      shiftr128(&copyd, 1, &copyd);
    446.  
      shiftr128(&adder, 1, &adder);
    447.  
      }
    448.  
      copy128(retDiv, &resDiv);
    449.  
      copy128(retMod, &resMod);
    450.  
      }
    451.  
      }
    452.  
       
    453.  
      void divmod256(uint256_t *l, uint256_t *r, uint256_t *retDiv,
    454.  
      uint256_t *retMod) {
    455.  
      uint256_t copyd, adder, resDiv, resMod;
    456.  
      uint256_t one;
    457.  
      clear256(&one);
    458.  
      UPPER(LOWER(one)) = 0;
    459.  
      LOWER(LOWER(one)) = 1;
    460.  
      uint32_t diffBits = bits256(l) - bits256(r);
    461.  
      clear256(&resDiv);
    462.  
      copy256(&resMod, l);
    463.  
      if (gt256(r, l)) {
    464.  
      copy256(retMod, l);
    465.  
      clear256(retDiv);
    466.  
      } else {
    467.  
      shiftl256(r, diffBits, &copyd);
    468.  
      shiftl256(&one, diffBits, &adder);
    469.  
      if (gt256(&copyd, &resMod)) {
    470.  
      shiftr256(&copyd, 1, &copyd);
    471.  
      shiftr256(&adder, 1, &adder);
    472.  
      }
    473.  
      while (gte256(&resMod, r)) {
    474.  
      if (gte256(&resMod, &copyd)) {
    475.  
      minus256(&resMod, &copyd, &resMod);
    476.  
      or256(&resDiv, &adder, &resDiv);
    477.  
      }
    478.  
      shiftr256(&copyd, 1, &copyd);
    479.  
      shiftr256(&adder, 1, &adder);
    480.  
      }
    481.  
      copy256(retDiv, &resDiv);
    482.  
      copy256(retMod, &resMod);
    483.  
      }
    484.  
      }
    485.  
       
    486.  
      static void reverseString(char *str, uint32_t length) {
    487.  
      uint32_t i, j;
    488.  
      for (i = 0, j = length - 1; i < j; i++, j--) {
    489.  
      uint8_t c;
    490.  
      c = str[i];
    491.  
      str[i] = str[j];
    492.  
      str[j] = c;
    493.  
      }
    494.  
      }
    495.  
       
    496.  
      bool tostring128(uint128_t *number, uint32_t baseParam, char *out,
    497.  
      uint32_t outLength) {
    498.  
      uint128_t rDiv;
    499.  
      uint128_t rMod;
    500.  
      uint128_t base;
    501.  
      copy128(&rDiv, number);
    502.  
      clear128(&rMod);
    503.  
      clear128(&base);
    504.  
      LOWER(base) = baseParam;
    505.  
      uint32_t offset = 0;
    506.  
      if ((baseParam < 2) || (baseParam > 16)) {
    507.  
      return false;
    508.  
      }
    509.  
      do {
    510.  
      if (offset > (outLength - 1)) {
    511.  
      return false;
    512.  
      }
    513.  
      divmod128(&rDiv, &base, &rDiv, &rMod);
    514.  
      out[offset++] = HEXDIGITS[(uint8_t)LOWER(rMod)];
    515.  
      } while (!zero128(&rDiv));
    516.  
      out[offset] = '';
    517.  
      reverseString(out, offset);
    518.  
      return true;
    519.  
      }
    520.  
       
    521.  
      bool tostring256(uint256_t *number, uint32_t baseParam, char *out,
    522.  
      uint32_t outLength) {
    523.  
      uint256_t rDiv;
    524.  
      uint256_t rMod;
    525.  
      uint256_t base;
    526.  
      copy256(&rDiv, number);
    527.  
      clear256(&rMod);
    528.  
      clear256(&base);
    529.  
      UPPER(LOWER(base)) = 0;
    530.  
      LOWER(LOWER(base)) = baseParam;
    531.  
      uint32_t offset = 0;
    532.  
      if ((baseParam < 2) || (baseParam > 16)) {
    533.  
      return false;
    534.  
      }
    535.  
      do {
    536.  
      if (offset > (outLength - 1)) {
    537.  
      return false;
    538.  
      }
    539.  
      divmod256(&rDiv, &base, &rDiv, &rMod);
    540.  
      out[offset++] = HEXDIGITS[(uint8_t)LOWER(LOWER(rMod))];
    541.  
      } while (!zero256(&rDiv));
    542.  
      out[offset] = '';
    543.  
      reverseString(out, offset);
    544.  
      return true;
    545.  
      }


     
  • 相关阅读:
    位运算符设置权限
    urlencode、urldecode、rawurlencode、rawurldecod
    二分查找法的mid值 整数溢出问题
    GIT 常用命令
    nginx配置反向代理转发
    PHP实现无限极分类
    PHP面试题目整理(持续更新)
    去除input的默认样式
    git 常用指令
    数组去重
  • 原文地址:https://www.cnblogs.com/it-tsz/p/11968630.html
Copyright © 2011-2022 走看看