Skip to content

Commit 84e1cdc

Browse files
authored
Merge pull request #18 from jvdp1/fix_2
replace function power of 2
2 parents 0f57c7a + 5de0f43 commit 84e1cdc

2 files changed

Lines changed: 30 additions & 13 deletions

File tree

src/modhash.fypp

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module modhash
33
use iso_fortran_env, only: int32, real32, real64
44
implicit none
55
private
6-
public :: hash, roundinguppower2
6+
public :: hash, next_power_of_2
77

88
integer(int32), parameter, public :: seed_hash = 305419896_int32
99

@@ -146,13 +146,30 @@ contains
146146
end if
147147
end function
148148

149-
elemental pure function roundinguppower2(x) result(next)
150-
integer(kind=int32), intent(in)::x
151-
integer(kind=int32)::next
149+
elemental pure function next_power_of_2(x) result(next)
150+
integer(kind=int32), intent(in) :: x
151+
integer(kind=int32) :: next
152152

153-
real(real64), parameter :: log2 = log(2._real64)
153+
integer(int32) :: bits
154154

155-
next = 2_int32 ** ceiling( log(real(x, real64)) / log2, kind=int32 )
155+
! If x is 0 or 1, the next power of 2 is 1
156+
if (x <= 1_int32) then
157+
next = 1_int32
158+
return
159+
end if
160+
161+
! Check if x is already a power of 2
162+
! A power of 2 has only one bit set, so iand(x, x-1) == 0
163+
if (iand(x, x - 1_int32) == 0_int32) then
164+
next = x
165+
return
166+
end if
167+
168+
! The position of the highest set bit determines the power
169+
bits = bit_size(x) - leadz(x)
170+
171+
! Shift 1 into the position above the highest set bit
172+
next = shiftl(1_int32, bits)
156173

157174
end function
158175

src/modtable.fypp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#:include "common.fypp"
22
module modtable
33
use iso_fortran_env, only: int32, real32
4-
use modhash, only: roundinguppower2, seed_hash, hash
4+
use modhash, only: next_power_of_2, seed_hash, hash
55
implicit none
66
private
77
#:for t,k,l,m in TYPES
@@ -117,8 +117,8 @@ contains
117117
integer(kind=int32), intent(in), optional :: nel
118118
type(table_${k}$_t) :: this
119119

120-
this%nel = roundinguppower2(default_nel)
121-
if (present(nel)) this%nel = roundinguppower2(nel)
120+
this%nel = next_power_of_2(default_nel)
121+
if (present(nel)) this%nel = next_power_of_2(nel)
122122

123123
this%filled = 0
124124

@@ -366,7 +366,7 @@ contains
366366
if (nfilled == 0_int32) then
367367
this%nel = default_nel
368368
else
369-
this%nel = roundinguppower2(int(1.3*nfilled, kind=int32))
369+
this%nel = next_power_of_2(int(1.3*nfilled, kind=int32))
370370
end if
371371
this%filled = 0
372372

@@ -399,8 +399,8 @@ contains
399399
integer(kind=int32), intent(in), optional :: nel
400400
type(table_arr${k}$_t) :: this
401401

402-
this%nel = roundinguppower2(default_nel)
403-
if (present(nel)) this%nel = roundinguppower2(nel)
402+
this%nel = next_power_of_2(default_nel)
403+
if (present(nel)) this%nel = next_power_of_2(nel)
404404

405405
this%filled = 0
406406

@@ -633,7 +633,7 @@ contains
633633
if (nfilled == 0_int32) then
634634
this%nel = 0_int32
635635
else
636-
this%nel = roundinguppower2(int(1.3*nfilled, kind=int32))
636+
this%nel = next_power_of_2(int(1.3*nfilled, kind=int32))
637637
end if
638638
this%filled = 0
639639

0 commit comments

Comments
 (0)