u64_shr Function

public pure function u64_shr(x, n) result(r)

Logical (zero-filling) right shift of a 64-bit word by n bits, 0 <= n <= 63. Written with ibits rather than ishft(x, -n) or the Fortran 2008 shiftr for the portability reasons given in the module documentation.

Arguments

Type IntentOptional Attributes Name
integer(kind=int64), intent(in) :: x
integer(kind=default_int), intent(in) :: n

Return Value integer(kind=int64)


Called by

proc~~u64_shr~~CalledByGraph proc~u64_shr u64_shr proc~mix64 mix64 proc~mix64->proc~u64_shr proc~pcg32_next_exponential_int pcg32_next_exponential_int proc~pcg32_next_exponential_int->proc~u64_shr proc~scale_by_mean scale_by_mean proc~pcg32_next_exponential_int->proc~scale_by_mean proc~pcg32_next_u64 pcg32_t%pcg32_next_u64 proc~pcg32_next_exponential_int->proc~pcg32_next_u64 proc~pcg32_step pcg32_step proc~pcg32_step->proc~u64_shr proc~rejection_mask~2 rejection_mask proc~rejection_mask~2->proc~u64_shr proc~scale_by_mean->proc~u64_shr proc~splitmix64_next_exponential_int splitmix64_next_exponential_int proc~splitmix64_next_exponential_int->proc~u64_shr proc~splitmix64_next_exponential_int->proc~scale_by_mean proc~splitmix64_next_u64 splitmix64_t%splitmix64_next_u64 proc~splitmix64_next_exponential_int->proc~splitmix64_next_u64 interface~next_exponential_int next_exponential_int interface~next_exponential_int->proc~pcg32_next_exponential_int interface~next_exponential_int->proc~splitmix64_next_exponential_int proc~pcg32_next pcg32_t%pcg32_next proc~pcg32_next->proc~pcg32_step proc~pcg32_next_poisson_int pcg32_next_poisson_int proc~pcg32_next_poisson_int->proc~pcg32_next_exponential_int proc~pcg32_next_u64->proc~pcg32_step proc~pcg32_seed pcg32_t%pcg32_seed proc~pcg32_seed->proc~pcg32_step proc~pcg32_uniform_below pcg32_uniform_below proc~pcg32_uniform_below->proc~rejection_mask~2 proc~pcg32_uniform_below->proc~pcg32_next_u64 proc~splitmix64_next splitmix64_t%splitmix64_next proc~splitmix64_next->proc~mix64 proc~splitmix64_next_poisson_int splitmix64_next_poisson_int proc~splitmix64_next_poisson_int->proc~splitmix64_next_exponential_int proc~splitmix64_uniform_below splitmix64_uniform_below proc~splitmix64_uniform_below->proc~rejection_mask~2 proc~splitmix64_uniform_below->proc~splitmix64_next_u64 proc~stream_seed stream_seed proc~stream_seed->proc~mix64 interface~next_poisson_int next_poisson_int interface~next_poisson_int->proc~pcg32_next_poisson_int interface~next_poisson_int->proc~splitmix64_next_poisson_int proc~pcg32_next_below pcg32_next_below proc~pcg32_next_below->proc~pcg32_next_u64 proc~pcg32_next_bernoulli_ppm pcg32_next_bernoulli_ppm proc~pcg32_next_bernoulli_ppm->proc~pcg32_uniform_below proc~pcg32_next_range pcg32_next_range proc~pcg32_next_range->proc~pcg32_uniform_below proc~pcg32_next_real_dp pcg32_next_real_dp proc~pcg32_next_real_dp->proc~pcg32_next_u64 proc~splitmix64_next_bernoulli_ppm splitmix64_next_bernoulli_ppm proc~splitmix64_next_bernoulli_ppm->proc~splitmix64_uniform_below proc~splitmix64_next_range splitmix64_next_range proc~splitmix64_next_range->proc~splitmix64_uniform_below proc~splitmix64_next_u64->proc~splitmix64_next proc~stream_for_pcg32 stream_for_pcg32 proc~stream_for_pcg32->proc~splitmix64_next proc~stream_for_pcg32->proc~stream_seed proc~stream_for_splitmix64 stream_for_splitmix64 proc~stream_for_splitmix64->proc~stream_seed interface~next_below next_below interface~next_below->proc~pcg32_next_below proc~splitmix64_next_below splitmix64_next_below interface~next_below->proc~splitmix64_next_below interface~next_bernoulli_ppm next_bernoulli_ppm interface~next_bernoulli_ppm->proc~pcg32_next_bernoulli_ppm interface~next_bernoulli_ppm->proc~splitmix64_next_bernoulli_ppm interface~next_range next_range interface~next_range->proc~pcg32_next_range interface~next_range->proc~splitmix64_next_range interface~next_real_dp next_real_dp interface~next_real_dp->proc~pcg32_next_real_dp proc~splitmix64_next_real_dp splitmix64_next_real_dp interface~next_real_dp->proc~splitmix64_next_real_dp interface~stream_for stream_for interface~stream_for->proc~stream_for_pcg32 interface~stream_for->proc~stream_for_splitmix64 proc~splitmix64_next_below->proc~splitmix64_next_u64 proc~splitmix64_next_real_dp->proc~splitmix64_next_u64 proc~pcg32_next_exponential_dp pcg32_next_exponential_dp proc~pcg32_next_exponential_dp->interface~next_real_dp proc~pcg32_next_normal_dp pcg32_next_normal_dp proc~pcg32_next_normal_dp->interface~next_real_dp proc~splitmix64_next_exponential_dp splitmix64_next_exponential_dp proc~splitmix64_next_exponential_dp->interface~next_real_dp proc~splitmix64_next_normal_dp splitmix64_next_normal_dp proc~splitmix64_next_normal_dp->interface~next_real_dp

Source Code

   pure function u64_shr(x, n) result(r)
      !! Logical (zero-filling) right shift of a 64-bit word by `n` bits,
      !! `0 <= n <= 63`. Written with `ibits` rather than `ishft(x, -n)` or the
      !! Fortran 2008 `shiftr` for the portability reasons given in the module
      !! documentation.
      integer(int64), intent(in) :: x
      integer(default_int), intent(in) :: n
      integer(int64) :: r

      ! A shift of zero is handled separately rather than falling through to
      ! `ibits(x, 0, 64)`. That call is conforming -- F2018 16.9.105 requires
      ! only POS + LEN <= BIT_SIZE(I) -- but LFortran 0.65.0 returns 0 from it
      ! for every input, while `ibits(x, 1, 63)` is correct.
      !
      ! test_pic_uint64's "shr by 0 is identity" is the regression test for
      ! this guard, not a reproducer of the defect: with the guard in place
      ! the offending call is never reached. To see the bug itself, call
      ! `ibits(x, 0, 64)` directly under LFortran.
      if (n <= 0_default_int) then
         r = x
      else
         r = ibits(x, n, 64 - n)
      end if
   end function u64_shr