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.  
      }


     
  • 相关阅读:
    Study Plan The TwentySecond Day
    Study Plan The Nineteenth Day
    Study Plan The TwentySeventh Day
    Study Plan The Twentieth Day
    Study Plan The TwentyFirst Day
    python实现进程的三种方式及其区别
    yum makecache
    JSONPath 表达式的使用
    oracle执行cmd的实现方法
    php daodb插入、更新与删除数据
  • 原文地址:https://www.cnblogs.com/it-tsz/p/11968630.html
Copyright © 2011-2022 走看看