One FNV-1a round: exclusive-or in a byte, then multiply by the prime.
The multiply is done in int64 and reduced modulo 2**32 by masking,
then folded back into the signed int32 range. Doing it directly in
int32 would overflow, which Fortran leaves undefined and which some
compilers trap on.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer(kind=int32), | intent(inout) | :: | state | |||
| integer(kind=int64), | intent(in) | :: | byte_value |
A single byte, 0 to 255. |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer(kind=int64), | private | :: | acc |
pure subroutine fnv1a_byte(state, byte_value) !! One FNV-1a round: exclusive-or in a byte, then multiply by the prime. !! !! The multiply is done in `int64` and reduced modulo 2**32 by masking, !! then folded back into the signed `int32` range. Doing it directly in !! `int32` would overflow, which Fortran leaves undefined and which some !! compilers trap on. integer(int32), intent(inout) :: state integer(int64), intent(in) :: byte_value !! A single byte, 0 to 255. integer(int64) :: acc acc = int(ieor(state, int(byte_value, int32)), int64) acc = iand(acc*FNV_PRIME, MASK_32) if (acc > INT32_MAX) acc = acc - TWO_POW_32 state = int(acc, int32) end subroutine fnv1a_byte