[PATCH 3 of 6 faster-obsmarkers v2] util: add getbefloat64

Augie Fackler raf at durin42.com
Tue Feb 3 12:31:11 CST 2015


# HG changeset patch
# User Augie Fackler <augie at google.com>
# Date 1422987441 18000
#      Tue Feb 03 13:17:21 2015 -0500
# Node ID b39c616665257bd5107ee68329fff3a126db255b
# Parent  0c18599df5197890d37fcb9397c5f9cfe7d770a8
util: add getbefloat64

As far as I can tell, this is wrong. double's format isn't strictly
specified in the C standard, but the wikipedia article implies that
platforms implementing optional Annex F "IEC 60559 floating-point
arithmetic" will work correctly.

My local C experts believe doing *((double *) &t) is a strict aliasing
violation, and that using a union is also one. Doing memcpy appears to
be the least-undefined behavior possible.

diff --git a/mercurial/util.h b/mercurial/util.h
--- a/mercurial/util.h
+++ b/mercurial/util.h
@@ -196,4 +196,17 @@ static inline void putbe32(uint32_t x, c
 	c[3] = (x) & 0xff;
 }
 
+static inline double getbefloat64(const char *c)
+{
+	const unsigned char *d = (const unsigned char *)c;
+	double ret;
+	int i;
+	uint64_t t = 0;
+	for (i = 0; i < 8; i++) {
+		t = (t<<8) + d[i];
+	}
+	memcpy(&ret, &t, sizeof(t));
+	return ret;
+}
+
 #endif /* _HG_UTIL_H_ */


More information about the Mercurial-devel mailing list