[pypy-commit] pypy default: Work around a MSVC bug
arigo
pypy.commits at gmail.com
Wed Aug 3 09:39:31 EDT 2016
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r86004:1512e98263d9
Date: 2016-08-03 15:41 +0200
http://bitbucket.org/pypy/pypy/changeset/1512e98263d9/
Log: Work around a MSVC bug
diff --git a/rpython/translator/c/src/float.h b/rpython/translator/c/src/float.h
--- a/rpython/translator/c/src/float.h
+++ b/rpython/translator/c/src/float.h
@@ -34,10 +34,39 @@
#define OP_CAST_FLOAT_TO_UINT(x,r) r = (Unsigned)(x)
#define OP_CAST_INT_TO_FLOAT(x,r) r = (double)(x)
#define OP_CAST_UINT_TO_FLOAT(x,r) r = (double)(x)
-#define OP_CAST_LONGLONG_TO_FLOAT(x,r) r = (double)(x)
-#define OP_CAST_ULONGLONG_TO_FLOAT(x,r) r = (double)(x)
+#define OP_CAST_LONGLONG_TO_FLOAT(x,r) r = rpy_cast_longlong_to_float(x)
+#define OP_CAST_ULONGLONG_TO_FLOAT(x,r) r = rpy_cast_ulonglong_to_float(x)
#define OP_CAST_BOOL_TO_FLOAT(x,r) r = (double)(x)
+#ifdef _WIN32
+/* The purpose of these two functions is to work around a MSVC bug.
+ The expression '(double)131146795334735160LL' will lead to bogus
+ rounding, but apparently everything is fine if we write instead
+ rpy_cast_longlong_to_float(131146795334735160LL). Tested with
+ MSVC 2008. Note that even if the two functions contain just
+ 'return (double)x;' it seems to work on MSVC 2008, but I don't
+ trust that there are no other corner cases.
+ http://stackoverflow.com/questions/33829101/incorrect-double-to-long-conversion
+*/
+static _inline double rpy_cast_longlong_to_float(long long x)
+{
+ unsigned int lo = (unsigned int)x;
+ double result = lo;
+ result += ((int)(x >> 32)) * 4294967296.0;
+ return result;
+}
+static _inline double rpy_cast_ulonglong_to_float(unsigned long long x)
+{
+ unsigned int lo = (unsigned int)x;
+ double result = lo;
+ result += ((unsigned int)(x >> 32)) * 4294967296.0;
+ return result;
+}
+#else
+# define rpy_cast_longlong_to_float(x) ((double)(x))
+# define rpy_cast_ulonglong_to_float(x) ((double)(x))
+#endif
+
#ifdef HAVE_LONG_LONG
#define OP_CAST_FLOAT_TO_LONGLONG(x,r) r = (long long)(x)
#define OP_CAST_FLOAT_TO_ULONGLONG(x,r) r = (unsigned long long)(x)
More information about the pypy-commit
mailing list