From: Eric W. <ewm...@gm...> - 2013-09-09 08:41:21
|
>> So you have me in a bind here. I don't know how to fix this. > > Using isinf seems to work, so changing the range checking to: > > if (v < -FLT_MAX || (v > FLT_MAX && !isinf(v))) > > works for me if I pass a Python float("inf") as well as your wrapped > INFINITY. Also numbers > FLT_MAX fail, which is good. > > isinf was introduced in the c99 standard, so I don't know that we can > rely on it always being available, which is a real nuisance as we need > to generate code that works with C89 too. Would there have to be a check for negative infinity? I'm pretty sure Visual Studio doesn't support isinf. They've decided to make everybody's lives difficult by not updating their compiler in 13 years and being 2 standards behind. This suggests a macro workaround for Visual Studio which I have not confirmed. http://stackoverflow.com/questions/2249110/how-do-i-make-a-portable-isnan-isinf-function #define isinf(x) (!_finite(x)) However, since Microsoft doesn't conform to the C99 spec on this, I don't know if their behavior about infinity and overflows will match what others do. I do not know what range of compilers you support. Semi-recent versions of gcc and clang should have no problems with isinf. I think Intel is okay too but have not verified. >> > The overflow checking goes hand in hand with overloading. Consider: So this is a little over my head. I'm not seeing how this is actually valuable in real world cases and how this can be guaranteed to be supported across supported SWIG languages. Specifically in C, there is no overloading, and in languages like Javascript and Lua, there is only a single "number" type (default is double). Trying to distinguish between storage types here, like between short and int seems totally ambiguous trying to bridge in those 3 languages, especially where the latter two are always dealing with double. > This need not be a problem > though as SWIG is designed to be customisable for those who don't like > the default approach. You can revert to any behaviour you like with a > few simple typemaps. So how would I do this for my library without needing to manually write a typemap for every API? This pattern of INFINITY as a valid value for float parameters is used throughout the entire library. It's not a small API. And we're already stretched just trying to keep up with both the JSCore and v8 customizations/differences. >>> Are you going to patch math.i to add in INFINITY too? >> >> I don't know how to solve the INFINITY problem in math.i. If you've >> seen my unit test and other posts on the topic, I've had to resort to: >> >> %rename(INFINITY) MYINFINITY; >> %inline %{ >> #include <math.h> >> /* This will allow us to bind the real INFINITY value through SWIG via >> MYINFINITY. Use %rename to fix the name. */ >> const double MYINFINITY = INFINITY; >> %} >> >> This is because compiler built-ins are often use to #define the value >> which SWIG can't handle. >> > Above looks okay to me for math.i. Ironically, I hit a bug in the Javascript implementations of %rename. I fixed v8, but have so far been unsuccessful at fixing JSCore. https://github.com/oliver----/swig-v8/issues/18#issuecomment-23926299 > >> Alternatively, this works in C as a fallback from what I've seen and I >> could do, >> #define INFINITY (1e1000) >> but that will yield compiler warnings for most people. >> >> And note that this works because overflow and INFINITY are >> indistinguishable which is the problem I'm trapped in right now. > > How about using the language specific representation of 'infinity' to > specify infinity? Sorry, could you clarify what you mean by that? The library I'm using does something like this to handle fallbacks: #ifndef INFINITY #ifdef _MSC_VER union MSVC_EVIL_FLOAT_HACK { unsigned __int8 Bytes[4]; float Value; }; static union MSVC_EVIL_FLOAT_HACK INFINITY_HACK = {{0x00, 0x00, 0x80, 0x7F}}; #define INFINITY (INFINITY_HACK.Value) #endif #ifdef __GNUC__ #define INFINITY (__builtin_inf()) #elif defined(__clang__) #if __has_builtin(__builtin_inf) #define INFINITY (__builtin_inf()) #endif #endif #ifndef INFINITY #define INFINITY (1e1000) #endif #endif |