On Thu, 18 Aug 2016, Martin Storsjö wrote:

On Thu, 18 Aug 2016, Kai Tietz wrote:

Hello Martin,

2016-08-18 15:31 GMT+02:00 Martin Storsjö <[email protected]>:
---
The (l)rint(f) functions call an inline assembly snippet to
do the rounding - that does seem to round in the right way, but I'm
not sure if that relies on the fpscr being set in the right mode?
---
 mingw-w64-crt/math/llrint.c  | 2 +-
 mingw-w64-crt/math/llrintf.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/mingw-w64-crt/math/llrint.c b/mingw-w64-crt/math/llrint.c
index 1fc11e8..d52fd15 100644
--- a/mingw-w64-crt/math/llrint.c
+++ b/mingw-w64-crt/math/llrint.c
@@ -11,7 +11,7 @@ long long llrint (double x)
#if defined(_AMD64_) || defined(__x86_64__) || defined(_X86_) || defined(__i386__)
   __asm__ __volatile__ ("fistpll %0"  : "=m" (retval) : "t" (x) : "st");
 #else
-  retval = (long long)x;
+  retval = x >= 0 ? (long long)floor(x + 0.5) : (long long)ceil(x - 0.5);
 #endif
   return retval;
 }
diff --git a/mingw-w64-crt/math/llrintf.c b/mingw-w64-crt/math/llrintf.c
index aabd81f..cb2b668 100644
--- a/mingw-w64-crt/math/llrintf.c
+++ b/mingw-w64-crt/math/llrintf.c
@@ -11,7 +11,7 @@ long long llrintf (float x)
#if defined(_AMD64_) || defined(__x86_64__) || defined(_X86_) || defined(__i386__)
   __asm__ __volatile__ ("fistpll %0"  : "=m" (retval) : "t" (x) : "st");
 #else
-  retval = (long long)x;
+ retval = x >= 0 ? (long long)floorf(x + 0.5) : (long long)ceilf(x - 0.5);
 #endif
   return retval;
 }
--
2.7.4

There is no other way to have here rounding, right? If so patch is ok.

Hmm, well strictly, it should probably follow what fesetround is set to.

I'll see if I can change it to use an inline assembly snippet, that relies on the floating point status register, instead of hardcording the rounding like this.

... and that turned out to be harder than I just thought, since there's no simple instruction for converting floats/doubles to 64 bit integers. (That's why clang calls support routines like __dtoi64 for this.)

So I guess we should either use fegetround to check the current mode and invoke different variants of floor/ceil with different offsets based on that, or try to include a reimplementation of something like __dtoi64 for this. I'd be more inclined to the former, here...

// Martin
------------------------------------------------------------------------------
_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to