Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
lemire committed Jan 31, 2024
1 parent 74063e0 commit 095643b
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 9 deletions.
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,6 @@ fastdiv_s32(a,M,d);// is a / d for all 32-bit a, d must not be one of -1, 1, or
In C++, it is much the same except that every function is in the `fastmod` namespace so you need to prefix the calls with `fastmod::` (e.g., `fastmod::is_divisible`).
The signed operations (`fastmod_s32` and `fastdiv_s32`) are currently unsupported under Visual Studio.
## Go version
* There is a Go version of this library: https://github.com/bmkessler/fastdiv
Expand Down
23 changes: 16 additions & 7 deletions include/fastmod.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,14 @@ namespace fastmod {
FASTMOD_API uint64_t mul128_u32(uint64_t lowbits, uint32_t d) {
return __umulh(lowbits, d);
}
FASTMOD_API uint64_t mul128_from_u64(uint64_t lowbits, uint64_t d) {
return __umulh(lowbits, d);
}
FASTMOD_API uint64_t mul128_s32(uint64_t lowbits, int32_t d) {
// not equivalent to ((__int128_t)lowbits * d) >> 64
return __mulh(lowbits, d);
if(d < 0) {
return mul128_from_u64(lowbits, (int64_t)d) - lowbits;
}
return mul128_u32(lowbits, d);
}


Expand All @@ -50,9 +55,14 @@ FASTMOD_API uint64_t mul128_s32(uint64_t lowbits, int32_t d) {
FASTMOD_API uint64_t mul128_u32(uint64_t lowbits, uint32_t d) {
return ((__uint128_t)lowbits * d) >> 64;
}

FASTMOD_API uint64_t mul128_from_u64(uint64_t lowbits, uint64_t d) {
return ((__uint128_t)lowbits * d) >> 64;
}
FASTMOD_API uint64_t mul128_s32(uint64_t lowbits, int32_t d) {
return ((__int128_t)lowbits * d) >> 64;
if(d < 0) {
return mul128_from_u64(lowbits, (int64_t)d) - lowbits;
}
return mul128_u32(lowbits, d);
}

// This is for the 64-bit functions.
Expand Down Expand Up @@ -124,11 +134,8 @@ FASTMOD_API int32_t fastmod_s32(int32_t a, uint64_t M, int32_t positive_d) {
return highbits - ((positive_d - 1) & (a >> 31));
}

#ifndef _MSC_VER

// fastdiv computes (a / d) given a precomputed M, assumes that d must not
// be one of -1, 1, or -2147483648
// Unsupported under VS, todo: fix.
FASTMOD_API int32_t fastdiv_s32(int32_t a, uint64_t M, int32_t d) {
uint64_t highbits = mul128_s32(M, a);
highbits += (a < 0 ? 1 : 0);
Expand All @@ -137,6 +144,8 @@ FASTMOD_API int32_t fastdiv_s32(int32_t a, uint64_t M, int32_t d) {
return (int32_t)(highbits);
}

#ifndef _MSC_VER

// What follows is the 64-bit functions.
// They are currently not supported on Visual Studio
// due to the lack of a mul128_u64 function.
Expand Down

0 comments on commit 095643b

Please sign in to comment.