1  /* Copyright (C) 1995-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <errno.h>
      19  #include <stdlib.h>
      20  #include <limits.h>
      21  #include <stdint.h>
      22  #include <sys/types.h>
      23  
      24  /* Global state for non-reentrant functions.  */
      25  struct drand48_data __libc_drand48_data;
      26  
      27  
      28  int
      29  __drand48_iterate (unsigned short int xsubi[3], struct drand48_data *buffer)
      30  {
      31    uint64_t X;
      32    uint64_t result;
      33  
      34    /* Initialize buffer, if not yet done.  */
      35    if (__glibc_unlikely (!buffer->__init))
      36      {
      37        buffer->__a = 0x5deece66dull;
      38        buffer->__c = 0xb;
      39        buffer->__init = 1;
      40      }
      41  
      42    /* Do the real work.  We choose a data type which contains at least
      43       48 bits.  Because we compute the modulus it does not care how
      44       many bits really are computed.  */
      45  
      46    X = (uint64_t) xsubi[2] << 32 | (uint32_t) xsubi[1] << 16 | xsubi[0];
      47  
      48    result = X * buffer->__a + buffer->__c;
      49  
      50    xsubi[0] = result & 0xffff;
      51    xsubi[1] = (result >> 16) & 0xffff;
      52    xsubi[2] = (result >> 32) & 0xffff;
      53  
      54    return 0;
      55  }