Abstract out conversion of a 256 bit endian number to a double, correcting errors and use it for determining any magnitude share diff.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
diff --git a/cgminer.c b/cgminer.c
index 715a630..2ea0d1f 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -3075,6 +3075,27 @@ static const double bits192 = 62771017353866807638357894232076664161023554444640
static const double bits128 = 340282366920938463463374607431768211456.0;
static const double bits64 = 18446744073709551616.0;
+/* Converts a little endian 256 bit value to a double */
+static double le256todouble(const void *target)
+{
+ uint64_t *data64;
+ double dcut64;
+
+ data64 = (uint64_t *)(target + 24);
+ dcut64 = le64toh(*data64) * bits192;
+
+ data64 = (uint64_t *)(target + 16);
+ dcut64 += le64toh(*data64) * bits128;
+
+ data64 = (uint64_t *)(target + 8);
+ dcut64 += le64toh(*data64) * bits64;
+
+ data64 = (uint64_t *)(target);
+ dcut64 += le64toh(*data64);
+
+ return dcut64;
+}
+
/*
* Calculate the work->work_difficulty based on the work->target
*/
@@ -3088,23 +3109,11 @@ static void calc_diff(struct work *work, double known)
work->work_difficulty = known;
else {
double d64, dcut64;
- uint64_t *data64;
d64 = truediffone;
if (opt_scrypt)
d64 *= (double)65536;
-
- data64 = (uint64_t *)(work->target + 24);
- dcut64 = le64toh(*data64);
-
- data64 = (uint64_t *)(work->target + 16);
- dcut64 += le64toh(*data64) * bits64;
-
- data64 = (uint64_t *)(work->target + 8);
- dcut64 += le64toh(*data64) * bits128;
-
- data64 = (uint64_t *)(work->target);
- dcut64 += le64toh(*data64) * bits192;
+ dcut64 = le256todouble(work->target);
work->work_difficulty = d64 / dcut64;
}
difficulty = work->work_difficulty;
@@ -3716,23 +3725,20 @@ static bool stale_work(struct work *work, bool share)
return false;
}
-static const uint64_t diffone = 0xFFFF000000000000ull;
-
static uint64_t share_diff(const struct work *work)
{
- uint64_t *data64, d64, ret;
bool new_best = false;
- char rhash[32];
+ double d64, s64;
+ uint64_t ret;
- swab256(rhash, work->hash);
+ d64 = truediffone;
if (opt_scrypt)
- data64 = (uint64_t *)(rhash + 2);
- else
- data64 = (uint64_t *)(rhash + 4);
- d64 = be64toh(*data64);
- if (unlikely(!d64))
- d64 = 1;
- ret = diffone / d64;
+ d64 *= (double)65536;
+ s64 = le256todouble(work->hash);
+ if (unlikely(!s64))
+ s64 = 0;
+
+ ret = round(d64 / s64);
cg_wlock(&control_lock);
if (unlikely(ret > best_diff)) {